diff --git a/.env.docker_example b/.env.example similarity index 50% rename from .env.docker_example rename to .env.example index e3603e5f..bf4da641 100644 --- a/.env.docker_example +++ b/.env.example @@ -2,32 +2,32 @@ NODE_ENV=development PORT=4040 JWT_SECRET=insert-random-secret-string-here -MONGO_HOST=mongodb://mongo/express-mongoose-es6-rest-api-development -MONGO_HOST_TEST=mongodb://mongo/express-mongoose-es6-rest-api-development-test +MONGO_HOST=mongodb://localhost/sedaily +MONGO_HOST_TEST=mongodb://localhost/sedaily-test MONGO_PORT=27017 -RACCOON_REDIS_URL=redis -RACCOON_REDIS_PORT=6379 -#RACCOON_REDIS_AUTH= - DEBUG=express-mongoose-es6-rest-api:* +EMAIL_FROM_ADDRESS=no-reply@example.com + FACEBOOK_ID=insert-facebook-app-id-here FACEBOOK_SECRET=insert-facebook-app-secret-here AWS_ACCESS_KEY_ID=YOUR_AWS_KEY AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET - +AWS_PROFILE_PIC_BUCKET_NAME=bucket-name +AWS_TOPIC_BUCKET_NAME=YOUR_BUCKET_NAME STRIPE_PUBLIC_KEY=public_key STRIPE_SECRET_KEY=secret_key - -AD_FREE_URL=https://google.com/ - SEND_GRID_KEY=send_grid_key EVENTS_API_BASE_URL=http://localhost:3000/api/v1/ MAILCHIMP_KEY=mailchimp_key -MAILCHIMP_LIST_ID=mailchimp_list_id \ No newline at end of file +MAILCHIMP_LIST_ID=mailchimp_list_id + +# These are public testing keys - https://developers.google.com/recaptcha/docs/faq +RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI +RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe diff --git a/.env.local_example b/.env.local_example deleted file mode 100644 index a257c6bb..00000000 --- a/.env.local_example +++ /dev/null @@ -1,33 +0,0 @@ -NODE_ENV=development -PORT=4040 -JWT_SECRET=insert-random-secret-string-here - -MONGO_HOST=mongodb://localhost/sed-test -MONGO_HOST_TEST=mongodb://localhost/sed-test -MONGO_PORT=27017 - -RACCOON_REDIS_URL=localhost -RACCOON_REDIS_PORT=6379 -#RACCOON_REDIS_AUTH= - -DEBUG=express-mongoose-es6-rest-api:* - -FACEBOOK_ID=insert-facebook-app-id-here -FACEBOOK_SECRET=insert-facebook-app-secret-here - - -AWS_ACCESS_KEY_ID=YOUR_AWS_KEY -AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET - - -STRIPE_PUBLIC_KEY=public_key -STRIPE_SECRET_KEY=secret_key - -AD_FREE_URL=https://google.com/ - -SEND_GRID_KEY=send_grid_key - -EVENTS_API_BASE_URL=http://localhost:3000/api/v1/ - -MAILCHIMP_KEY=mailchimp_key -MAILCHIMP_LIST_ID=mailchimp_list_id \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index b6e28362..4021c933 100644 --- a/.eslintrc +++ b/.eslintrc @@ -30,7 +30,8 @@ ], "no-underscore-dangle": [ 0 - ] + ], + "arrow-body-style":"off" }, "env": { "node": true, diff --git a/.gitignore b/.gitignore index 14028f6d..bc4a3ff5 100644 --- a/.gitignore +++ b/.gitignore @@ -54,5 +54,12 @@ node_modules *.swp *.swo +# Database Migrations +.migrate + # Redis Database File *.rdb + +# CI builds +devops/dump +.vscode/settings.json diff --git a/.travis.yml b/.travis.yml index b8faa6fc..42a5a5db 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,27 @@ language: node_js node_js: - - "6.11" + - "10.19.0" +sudo: required services: - mongodb - - redis-server + - docker cache: directories: - node_modules git: depth: 3 -script: - # - yarn test:check-coverage - - npm run test -after_script: - # - yarn report-coverage +stages: + - test + - name: docker + if: branch = master AND type = push +jobs: + include: + - stage: test + script: + - npm run lint + - npm run test + - npm run build + - stage: docker + script: + - ./devops/build-api.sh + - cd devops; ./build-mongodb.sh diff --git a/Dockerfile b/Dockerfile index 5e2bb8ac..5a6617fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # take default image of node boron i.e node 6.x -FROM node:6.10.1 +FROM node:10.19.0 MAINTAINER Kunal Kapadia diff --git a/README.md b/README.md index 965780e6..633d035c 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,42 @@ [![logo](https://i.imgur.com/3OtP3p8.png)](https://softwareengineeringdaily.com/) -[![Build Status](https://travis-ci.org/SoftwareEngineeringDaily/software-engineering-daily-api.svg?branch=travis-fix)](https://travis-ci.org/SoftwareEngineeringDaily/software-engineering-daily-api) - -# SEDaily-API - -The backend services and API for the Software Engineering Daily [Android](https://github.com/SoftwareEngineeringDaily/SEDaily-Android), [iOS](https://github.com/SoftwareEngineeringDaily/se-daily-iOS), and [web front end](https://github.com/SoftwareEngineeringDaily/sedaily-front-end). - -## Set up (local) -### *[More details here...](https://softwareengineeringdaily.github.io/Backend/gettingstarted/) - - Install and run a local redis client - - Install and run a local mongo client - - `cp .env.local_example .env` - - `npm install` or `yarn install` - - `npm start` or `yarn start` - - check package.json for other builds - - use curl or Postman to make requests - - view swagger api docs at HOST/api/docs - -## Using Docker - - `cp .env.docker_example .env` - - Run `docker-compose up` - - If dependencies are updated in package.json, run `docker-compose down` and then `docker-compose up --build`. This will remove the old container and rebuild the API image which installs the new dependencies. +[![Build Status](https://travis-ci.org/SoftwareEngineeringDaily/software-engineering-daily-api.svg?branch=master)](https://travis-ci.org/SoftwareEngineeringDaily/software-engineering-daily-api) + +# Software Engineering Daily API + +The backend services and API for the Software Engineering Daily [Android](https://github.com/SoftwareEngineeringDaily/SEDaily-Android), [iOS](https://github.com/SoftwareEngineeringDaily/se-daily-iOS), and [front end](https://github.com/SoftwareEngineeringDaily/sedaily-front-end) clients. + +### Getting Started + +The [Software Daily](https://www.softwaredaily.com) API uses MongoDB as the data store. You'll need MongoDB running locally. This requires an OS-specific install of [Docker](https://docs.docker.com/install/) and [Docker Compose](https://docs.docker.com/compose/install/#prerequisites). During the CI process for the the API, the MongoDB image data is seeded from the [staging environment](https://sedaily-frontend-staging.herokuapp.com). + +``` +# clone the project +git clone https://github.com/SoftwareEngineeringDaily/software-engineering-daily-api.git +cd software-engineering-daily-api/ + +# setup environment variables +cp .env.example .env + +# run mondodb container +docker-compose up -d + +# install dependencies +npm install + +# serve with hot reload at localhost:4040 +npm start + +# test api +curl localhost:4040/api/posts +``` + +View the swagger api docs at http://localhost:4040/api/docs + +### Contributing + +Fork the repository and create a branch off of `master`. When your feature is ready, submit a pull request for the `master` branch. Be sure to include a short description of the feature or pull request and reference any related issues. The project is hosted on Heroku so if you would like a review app created just request it in the PR. + +After the Travis-CI tests are successful and your pull request is approved, an admin will merge the PR. Any commits merged to `master` are deployed to the front end [staging environment](https://sedaily-frontend-staging.herokuapp.com). Once everything looks good an admin will promote staging to production and your feature will be live! + +We have an active Slack community that you can reach out to for more information or just to chat with anyone. Check out the [Slack Channel SED app development](https://softwaredaily.slack.com/app_redirect?channel=sed_app_development) slack channel. Also see the [Open Source Guide](https://softwareengineeringdaily.github.io/). diff --git a/app.json b/app.json index 31c7970b..b053efde 100644 --- a/app.json +++ b/app.json @@ -1,8 +1,51 @@ { "name": "software-engineering-daily-api", + "stack": "heroku-18", "scripts": { }, "env": { + "JWT_SECRET": { + "required": true + }, + "MONGO_HOST": { + "required": true + }, + "MONGO_HOST_TEST": { + "required": true + }, + "AWS_ACCESS_KEY_ID": { + "required": true + }, + "AWS_SECRET_ACCESS_KEY": { + "required": true + }, + "AWS_PROFILE_PIC_BUCKET_NAME": { + "required": true + }, + "STRIPE_PUBLIC_KEY": { + "required": true + }, + "STRIPE_SECRET_KEY": { + "required": true + }, + "SEND_GRID_KEY": { + "required": true + }, + "MAILCHIMP_KEY": { + "required": true + }, + "MAILCHIMP_LIST_ID": { + "required": true + }, + "RECAPTCHA_SITE_KEY": { + "required": true + }, + "RECAPTCHA_SECRET_KEY": { + "required": true + }, + "EMAIL_FROM_ADDRESS": { + "required": true + } }, "formation": { }, diff --git a/bin/development.sh b/bin/development.sh deleted file mode 100644 index 05cae5a8..00000000 --- a/bin/development.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -# --build: Build images before starting containers. -# --abort-on-container-exit: Stops all containers if any container is stopped -docker-compose up --build --abort-on-container-exit diff --git a/bin/test.sh b/bin/test.sh deleted file mode 100644 index 241084ac..00000000 --- a/bin/test.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bash - -# --build: Build images before starting containers. -# --abort-on-container-exit: Stops all containers if any container is stopped -docker-compose -f 'docker-compose.test.yml' -p ci up --build --abort-on-container-exit -exit $(docker wait ci_express-mongoose-es6-rest-api_1) diff --git a/config/config.js b/config/config.js index 81553b47..979aa338 100644 --- a/config/config.js +++ b/config/config.js @@ -9,9 +9,7 @@ const envVarsSchema = Joi.object({ .allow(['development', 'production', 'test', 'provision']) .default('development'), BASE_URL: Joi.string() - // .allow(['https://www.softwaredaily.com', 'http://localhost:4040']) .default('https://www.softwaredaily.com'), - EVENTS_API_BASE_URL: Joi.string().required(), SEND_GRID_KEY: Joi.string().required(), PORT: Joi.number() .default(4040), @@ -23,22 +21,26 @@ const envVarsSchema = Joi.object({ }), JWT_SECRET: Joi.string().required() .description('JWT Secret required to sign'), - AD_FREE_URL: Joi.string().required() - .description('URL for ad free podcasts'), MONGO_HOST: Joi.string().required() .description('Mongo DB host url'), MONGO_HOST_TEST: Joi.string() .description('Mongo DB test host url'), MONGO_PORT: Joi.number() .default(27017), - FACEBOOK_ID: Joi.string().required() - .description('Facbook application id'), - FACEBOOK_SECRET: Joi.string().required() - .description('Facebook application secret'), + MONGO_COLLECTION_PREFIX: Joi.string().default('') + .description('Prefix used in all collection names'), MAILCHIMP_KEY: Joi.string().required() .description('Mailchimp API key'), MAILCHIMP_LIST_ID: Joi.string().required() - .description('Mailchimp list id') + .description('Mailchimp list id'), + RECAPTCHA_SITE_KEY: Joi.string().required() + .description('Recaptcha site key'), + RECAPTCHA_SECRET_KEY: Joi.string().required() + .description('Recaptcha secret key'), + AWS_PROFILE_PIC_BUCKET_NAME: Joi.string().required() + .description('S3 bucket for storing profile pictures'), + EMAIL_FROM_ADDRESS: Joi.string().required() + .description('Email address listed in FROM section of emails') }).unknown() .required(); @@ -51,23 +53,36 @@ const config = { env: envVars.NODE_ENV, port: envVars.PORT, baseUrl: envVars.BASE_URL, + serverUrl: envVars.SERVER_URL, sendGridKey: envVars.SEND_GRID_KEY, mongooseDebug: envVars.MONGOOSE_DEBUG, - adFreeURL: envVars.AD_FREE_URL, jwtSecret: envVars.JWT_SECRET, - eventStreamUrl: envVars.EVENTS_API_BASE_URL, mongo: { host: envVars.MONGO_HOST, test: envVars.MONGO_HOST_TEST, - port: envVars.MONGO_PORT - }, - facebook: { - clientID: envVars.FACEBOOK_ID, - clientSecret: envVars.FACEBOOK_SECRET + port: envVars.MONGO_PORT, + collectionPrefix: envVars.MONGO_COLLECTION_PREFIX ? `${envVars.MONGO_COLLECTION_PREFIX}-` : '' }, mailchimp: { mailchimpKey: envVars.MAILCHIMP_KEY, mailchimpList: envVars.MAILCHIMP_LIST_ID + }, + recaptcha: { + siteKey: envVars.RECAPTCHA_SITE_KEY, + secretKey: envVars.RECAPTCHA_SECRET_KEY + }, + aws: { + profilePicBucketName: envVars.AWS_PROFILE_PIC_BUCKET_NAME, + topicBucketName: envVars.AWS_TOPIC_BUCKET_NAME, + }, + email: { + fromAddress: envVars.EMAIL_FROM_ADDRESS + }, + cron: { + RSS: { + time: '0 15 9,10,11,12,14,16,19,21 * * *', + timeZone: null + } } }; diff --git a/config/express.js b/config/express.js index dcbd207f..fb07133f 100644 --- a/config/express.js +++ b/config/express.js @@ -1,5 +1,6 @@ import express from 'express'; import logger from 'morgan'; +import * as Sentry from '@sentry/node'; import bodyParser from 'body-parser'; import cookieParser from 'cookie-parser'; import compress from 'compression'; @@ -10,6 +11,14 @@ import httpStatus from 'http-status'; import expressWinston from 'express-winston'; import expressValidation from 'express-validation'; import helmet from 'helmet'; + +// import http from 'http'; +// import https from 'https'; +// import url from 'url'; +// import HttpsProxyAgent from 'https-proxy-agent'; +import { createProxyMiddleware } from 'http-proxy-middleware'; +// import request from 'request'; + import winstonInstance from './winston'; import routes from '../server/routes/index.route'; import config from './config'; @@ -17,6 +26,16 @@ import APIError from '../server/helpers/APIError'; const app = express(); +// Setup Sentry +Sentry.init({ + dsn: process.env.SENTRY_DSN, + environment: process.env.NODE_ENV, + debug: (config.env === 'development'), +}); + +// The request handler must be the first middleware on the app +app.use(Sentry.Handlers.requestHandler()); + if (config.env === 'development') { app.use(logger('dev')); } @@ -52,6 +71,9 @@ if (config.env === 'development') { // mount all routes on /api path app.use('/api', routes); +// The error handler must be before any other error middleware +app.use(Sentry.Handlers.errorHandler()); + // if error is not an instanceOf APIError, convert it. app.use((err, req, res, next) => { if (err instanceof expressValidation.ValidationError) { @@ -66,6 +88,10 @@ app.use((err, req, res, next) => { return next(err); }); +if (process.env.FEATURE_SERVE_FRONT === true) { + app.use('/', express.static(`${__dirname}/front-dist`)); +} + // catch 404 and forward to error handler app.use((req, res, next) => { const err = new APIError('API not found', httpStatus.NOT_FOUND); @@ -79,6 +105,94 @@ if (config.env !== 'test') { })); } +// handle static IP proxy +if (config.serverUrl) { + app.use(process.env.QUOTAGUARDSTATIC_URL, createProxyMiddleware({ + target: config.serverUrl, + headers: { + accept: 'application/json', + method: 'GET', + }, + changeOrigin: true + })); + + // HTTP/HTTPS proxy to connect to + // const proxy = process.env.QUOTAGUARDSTATIC_URL; + // const endpoint = config.serverUrl; + // var options = url.parse(endpoint); + + // // create an instance of the `HttpsProxyAgent` class with the proxy server information + // var agent = new HttpsProxyAgent(proxy); + // options.agent = agent; + + // https.get(options, function (res) { + // console.log('"response" event!', res.headers); + // res.pipe(process.stdout); + // }); + + // const options = { + // proxy: process.env.QUOTAGUARDSTATIC_URL, + // url: config.serverUrl, + // headers: { + // 'User-Agent': 'node.js', + // }, + // }; + + // request(options, (error, response, body) => { + // console.log(`uri: ${config.serverUrl}`); + // console.log(`Error ${error}`); + // console.log(`Response: ${response}`); + // console.log(`Body: ${body}`); + + // if (!error && response.statusCode === 200) { + // console.log(body); + // } + // }); + + + // const proxy = process.env.QUOTAGUARDSTATIC_URL; + // const agent = new HttpsProxyAgent(proxy); + // const options = { + // uri: config.serverUrl, + // method: 'POST', + // headers: { + // 'content-type': 'application/x-www-form-urlencoded' + // }, + // agent, + // timeout: 10000, + // followRedirect: true, + // maxRedirects: 10, + // // body: "name=john" + // }; + + // request(options, (error, response, body) => { + // console.log(`uri: ${config.serverUrl}`); + // console.log(`Error ${error}`); + // console.log(`Response: ${response}`); + // console.log(`Body: ${body}`); + // }); + + + // const proxy = url.parse(process.env.QUOTAGUARDSTATIC_URL); + // const target = url.parse(config.serverUrl); + // const options = { + // hostname: proxy.hostname, + // port: proxy.port || 80, + // path: target.href, + // headers: { + // // eslint-disable no-buffer-constructor + // 'Proxy-Authorization': `Basic ${new Buffer(proxy.auth).toString('base64')}`, + // Host: target.hostname, + // } + // }; + + // http.get(options, (res) => { + // console.log('config.serverUrl ', config.serverUrl); + // res.pipe(process.stdout); + // return console.log('status code', res.statusCode); + // }); +} + // error handler, send stacktrace only during development app.use(( err, diff --git a/config/param-validation.js b/config/param-validation.js index 19e3a8ba..63392953 100644 --- a/config/param-validation.js +++ b/config/param-validation.js @@ -4,13 +4,12 @@ export default { // UPDATE /api/users/:userId updateUser: { body: { - username: Joi.string().required(), name: Joi.string().required(), bio: Joi.string().allow(''), about: Joi.string().allow(''), github: Joi.string().allow(''), linkedin: Joi.string().allow(''), - twitter: Joi.string().allow(''), + // twitter: Joi.string().allow(), // alow to be blank and removal website: Joi.string().allow(''), isAvatarSet: Joi.boolean().required(), email: Joi.string().email().allow(''), @@ -64,16 +63,18 @@ export default { password: Joi.string().required() } }, + // POST /api/auth/register register: { body: { - username: Joi.string().required(), password: Joi.string().required(), + // Should be required once mobile apps get updated: name: Joi.string(), + lastName: Joi.string(), bio: Joi.string().allow(''), website: Joi.string().allow(''), - email: Joi.string().email().allow('') + email: Joi.string().email().allow(''), } }, @@ -81,13 +82,12 @@ export default { relatedLinkCreate: { body: { url: Joi.string().required(), - title: Joi.string().required() } }, comment: { body: { - content: Joi.string().required() + content: Joi.string().allow(''), } } }; diff --git a/config/websocket.js b/config/websocket.js new file mode 100644 index 00000000..82e4b6ba --- /dev/null +++ b/config/websocket.js @@ -0,0 +1,83 @@ + +import jwt from 'jsonwebtoken'; +import config from './config'; +import notificationCtrl from '../server/controllers/notification.controller'; + +let server; +let sockets = []; + +function setServer(io) { + server = io; + server.on('connection', (socket) => { + socketEvents(socket); + }); +} + +function askRegister(socket) { + socket.emit('app.register'); +} + +function registerSocket(socket, token) { + try { + const data = jwt.verify(token, config.jwtSecret); + socket.userData = data; // eslint-disable-line no-param-reassign + socket.registered = true; // eslint-disable-line no-param-reassign + socket.join('registered'); + return true; + } catch (e) { + return false; + } +} + +function socketEvents(socket) { + sockets.push(socket); + askRegister(socket); + + socket.on('disconnect', () => { + clearDisconnected(); + }); + + socket.on('register', ({ token }) => { + const register = registerSocket(socket, token); + if (register) socket.emit('app.registered'); + + notificationCtrl.sendNotifications(socket.userData._id); + }); + + socket.on('markread.all', () => { + if (socket.userData && socket.userData._id) { + notificationCtrl.markReadAll(socket.userData._id); + } + }); +} + +function clearDisconnected() { + sockets = sockets.filter(s => s.connected); +} + +function isConnected(userId) { + return sockets.find(s => s.registered && s.userData && s.userData._id === userId && s.connected); +} + +function to(userId) { + const userSockets = sockets.filter((s) => { + return s.registered && s.userData && s.userData._id === userId && s.connected; + }); + + return { + emit(event, data) { + userSockets.forEach((socket) => { + socket.emit(event, data); + }); + } + }; +} + +export default { + get ws() { + return server; + }, + setServer, + isConnected, + to +}; diff --git a/devops/.env.ci b/devops/.env.ci new file mode 100644 index 00000000..fb334b9e --- /dev/null +++ b/devops/.env.ci @@ -0,0 +1,34 @@ +NODE_ENV=development +PORT=4040 +JWT_SECRET=insert-random-secret-string-here + +MONGO_HOST=mongodb://mongo/sedaily +MONGO_HOST_TEST=mongodb://mongo/sedaily-test +MONGO_PORT=27017 + +DEBUG=sedaily:* + +EMAIL_FROM_ADDRESS=no-reply@example.com + +STRIPE_PUBLIC_KEY=public_key +STRIPE_SECRET_KEY=secret_key + +ALGOLIA_APP_ID=algolia_app_id +ALGOLIA_API_KEY=algolia_api_key +ALGOLIA_POSTS_INDEX=algolia_posts_index + +AWS_ACCESS_KEY_ID=YOUR_AWS_KEY +AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET +AWS_PROFILE_PIC_BUCKET_NAME=YOUR_BUCKET_NAME +AWS_TOPIC_BUCKET_NAME=YOUR_BUCKET_NAME + +SEND_GRID_KEY=send_grid_key + +EVENTS_API_BASE_URL=http://localhost:3000/api/v1/ + +MAILCHIMP_KEY=mailchimp_key +MAILCHIMP_LIST_ID=mailchimp_list_id + +# These are public testing keys - https://developers.google.com/recaptcha/docs/faq +RECAPTCHA_SITE_KEY=6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI +RECAPTCHA_SECRET_KEY=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe diff --git a/devops/build-api.sh b/devops/build-api.sh new file mode 100755 index 00000000..0bdcf309 --- /dev/null +++ b/devops/build-api.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# builds sedaiy-rest-api image for Continuous Integration (CI) purposes + + +echo "Building API Docker image" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +REPO_DIR=$(dirname $DIR) + +DOCKER_IMAGE="softwaredaily/sedaily-rest-api" + +# copy docker file to repo root +cp $DIR/ci.Dockerfile $REPO_DIR/ci.Dockerfile + +docker build -f $REPO_DIR/ci.Dockerfile -t $DOCKER_IMAGE $REPO_DIR #--no-cache + +rm $REPO_DIR/ci.Dockerfile + +# must be part the organization +echo $DOCKER_PASSWORD | docker login -u "$DOCKER_USERNAME" --password-stdin + +docker push $DOCKER_IMAGE diff --git a/devops/build-mongodb.sh b/devops/build-mongodb.sh new file mode 100755 index 00000000..47d6d04e --- /dev/null +++ b/devops/build-mongodb.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +if [ -f .env ]; then + echo ".env file found in devops directory. Using testing environment variables..." + source .env +fi + +DOCKER_IMAGE="softwaredaily/sedaily-mongo" + +function dumpDatabase() { + mongodump --quiet --host $MONGO_CI_HOST --port $MONGO_CI_PORT --username $MONGO_CI_USER --password $MONGO_CI_PASS -d $MONGO_CI_DB --excludeCollection users --excludeCollection passwordresets --excludeCollection forumthreads --excludeCollection forumthreadsCI --out ./backup +} + +function dumpAdminUser() { + mongodump --quiet --host $MONGO_CI_HOST --username $MONGO_CI_USER --password $MONGO_CI_PASS --port $MONGO_CI_PORT -d $MONGO_CI_DB --collection users --query '{ email: { $eq: "forum_admin@softwaredaily.com" } }' --out ./backup +} + +function dumpForumThreads() { + # remove all documents from forumthreadsCI collection + tmpFile=$(mktemp) + echo "use ${MONGO_CI_DB};" > ${tmpFile} + echo "db.forumthreadsCI.remove({});" >> ${tmpFile} + mongo --quiet --host ${MONGO_CI_HOST} --port ${MONGO_CI_PORT} --username ${MONGO_CI_USER} --password ${MONGO_CI_PASS} --authenticationDatabase ${MONGO_CI_DB} <${tmpFile} + rm ${tmpFile} + + # copy all documents from forumThreads collection to forumThreadsCI collection + mongodump --quiet --host $MONGO_CI_HOST --port $MONGO_CI_PORT --username $MONGO_CI_USER --password $MONGO_CI_PASS -d $MONGO_CI_DB -c forumthreads --out ./forumthreads + mongorestore --quiet --host $MONGO_CI_HOST --port $MONGO_CI_PORT --username $MONGO_CI_USER --password $MONGO_CI_PASS -d $MONGO_CI_DB -c forumthreadsCI ./forumthreads/${MONGO_CI_DB}/forumthreads.bson + rm -rf forumthreads + + # set all authors to admin + tmpFile=$(mktemp) + echo "use ${MONGO_CI_DB};" > ${tmpFile} + echo "user=db.users.findOne({email: \"forum_admin@softwaredaily.com\"})._id;" >> ${tmpFile} + echo "db.forumthreadsCI.updateMany({}, {\$set: {author: user}});" >> ${tmpFile} + mongo --quiet --host ${MONGO_CI_HOST} --port ${MONGO_CI_PORT} --username ${MONGO_CI_USER} --password ${MONGO_CI_PASS} --authenticationDatabase ${MONGO_CI_DB} <${tmpFile} + rm ${tmpFile} + + # dump forumThreadsCI to forumthreads collection locally + mongodump --quiet --host $MONGO_CI_HOST --port $MONGO_CI_PORT --username $MONGO_CI_USER --password $MONGO_CI_PASS -d $MONGO_CI_DB -c forumthreadsCI --out ./backup + mv backup/${MONGO_CI_DB}/forumthreadsCI.bson backup/${MONGO_CI_DB}/forumthreads.bson + mv backup/${MONGO_CI_DB}/forumthreadsCI.metadata.json backup/${MONGO_CI_DB}/forumthreads.metadata.json +} + + +dumpDatabase +dumpAdminUser +dumpForumThreads + +mkdir dump/ +mv backup/$MONGO_CI_DB/* dump/ +rm -rf backup + +docker build -f mongo.Dockerfile -t $DOCKER_IMAGE . --no-cache + +rm -rf dump + +# must be part the organization +echo $DOCKER_PASSWORD | docker login -u "$DOCKER_USERNAME" --password-stdin + +docker push $DOCKER_IMAGE diff --git a/devops/ci.Dockerfile b/devops/ci.Dockerfile new file mode 100644 index 00000000..8fbc249b --- /dev/null +++ b/devops/ci.Dockerfile @@ -0,0 +1,27 @@ +FROM node:10.19.0 + +# create app directory in container +RUN mkdir -p /app + +# set /app directory as default working directory +WORKDIR /app + +# only copy package.json initially so that `RUN yarn` layer is recreated only +# if there are changes in package.json +ADD package.json package-lock.json /app/ + + +# --no-save: Don’t generate a package-lock.json lockfile +RUN npm install --no-save --silent + +# copy all file from current dir to /app in container +COPY . /app/ + +# overwrite .env file with example +COPY ./devops/.env.ci /app/.env + +# expose port 4040 +EXPOSE 4040 + +# cmd to start service +CMD [ "npm", "start" ] diff --git a/devops/mongo.Dockerfile b/devops/mongo.Dockerfile new file mode 100644 index 00000000..42e5c373 --- /dev/null +++ b/devops/mongo.Dockerfile @@ -0,0 +1,10 @@ +# https://stackoverflow.com/questions/39282957/mongorestore-in-a-dockerfile +FROM mongo:3.4.10 + +COPY dump/ /home/dump + +COPY mongo.sh /home/mongo.sh + +RUN chmod 777 /home/mongo.sh + +CMD /home/mongo.sh diff --git a/devops/mongo.sh b/devops/mongo.sh new file mode 100755 index 00000000..43b2bfeb --- /dev/null +++ b/devops/mongo.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Initialize a mongo data folder and logfile +mkdir -p /data/db +touch /var/log/mongodb.log +chmod 777 /var/log/mongodb.log + +# Start mongodb with logging +# --logpath Without this mongod will output all log information to the standard output. +# --logappend Ensure mongod appends new entries to the end of the logfile. We create it first so that the below tail always finds something +/entrypoint.sh mongod --logpath /var/log/mongodb.log --logappend & + +# Wait until mongo logs that it's ready (or timeout after 60s) +COUNTER=0 +grep -q 'waiting for connections on port' /var/log/mongodb.log +while [[ $? -ne 0 && $COUNTER -lt 60 ]] ; do + sleep 2 + let COUNTER+=2 + echo "Waiting for mongo to initialize... ($COUNTER seconds so far)" + grep -q 'waiting for connections on port' /var/log/mongodb.log +done + + +# Restore from dump +echo "Restoring database from dump..." +mongorestore --db sedaily --quiet /home/dump + +echo "Mongo restore finished!" +# Keep container running +tail -f /dev/null diff --git a/docker-compose.test.yml b/docker-compose.test.yml deleted file mode 100644 index cff969cf..00000000 --- a/docker-compose.test.yml +++ /dev/null @@ -1,42 +0,0 @@ -version: '2' - -services: - express-mongoose-es6-rest-api: - build: - context: . - - image: express-mongoose-es6-rest-api:latest - - volumes: - # Mounts the project directory on the host to /app inside the container, - # allowing you to modify the code without having to rebuild the image. - - .:/app - # Just specify a path and let the Engine create a volume. - # Data present in the base image at the specified mount point will be copied - # over to the new volume upon volume initialization. - # node_modules from this new volume will be used and not from your local dev env. - - /app/node_modules/ - - # Set environment variables from this file - env_file: - - .env - - # Overwrite any env var defined in .env file (if required) - environment: - - MONGO_HOST=mongodb://mongo/express-mongoose-es6-rest-api-test - - DEBUG=express-mongoose-es6-rest-api:* - - # Link to containers in another service. - # Links also express dependency between services in the same way as depends_on, - # so they determine the order of service startup. - links: - - mongo - - command: - - /bin/bash - - -c - - yarn --pure-lockfile && yarn test - mongo: - image: "mongo:3.4.2" - ports: - - "27017:27017" diff --git a/docker-compose.yml b/docker-compose.yml index c2ecf9d4..e074d2f9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,41 +1,8 @@ version: '2' services: - redis: - image: redis:4 - container_name: sedaily-redis -# ports: -# - "6379:6379" - express-mongoose-es6-rest-api: - build: - context: . - container_name: sedaily-rest-api - volumes: - # Mounts the project directory on the host to /app inside the container, - # allowing you to modify the code without having to rebuild the image. - - .:/app - # Just specify a path and let the Engine create a volume. - # Data present in the base image at the specified mount point will be copied - # over to the new volume upon volume initialization. - # node_modules from this new volume will be used and not from your local dev env. - - /app/node_modules/ - - # Expose ports [HOST:CONTAINER} - ports: - - "4040:4040" - - # Set environment variables from this file - env_file: - - .env - - # Link to containers in another service. - # Links also express dependency between services in the same way as depends_on, - # so they determine the order of service startup. - links: - - mongo - - redis mongo: - image: "mongo:3.4.10" + image: softwaredaily/sedaily-mongo container_name: sedaily-mongo ports: - "27017:27017" diff --git a/index.js b/index.js index 69011f92..dcdf6832 100644 --- a/index.js +++ b/index.js @@ -1,10 +1,22 @@ // adding comment import mongoose from 'mongoose'; import util from 'util'; +import SocketIO from 'socket.io'; +import Http from 'http'; // config should be imported before importing any other file import config from './config/config'; -import app from './config/express'; +import appExpress from './config/express'; +import websocket from './config/websocket'; +import Cron from './server/controllers/cron.controller'; + +const app = Http.createServer(appExpress); +const io = SocketIO(app); + +websocket.setServer(io); + +// cron jobs control +const cron = new Cron(); const debug = require('debug')('express-mongoose-es6-rest-api:index'); @@ -29,6 +41,12 @@ mongoose.connect(mongoUri, { mongoose.connection.on('error', () => { throw new Error(`unable to connect to database: ${mongoUri}`); }); +mongoose.connection.on('connected', () => { + cron.start(); +}); +mongoose.connection.on('disconnected', () => { + cron.pause(); +}); // print mongoose logs in dev env if (config.MONGOOSE_DEBUG) { diff --git a/megaphone-all_fields.json b/megaphone-all_fields.json new file mode 100644 index 00000000..c1444839 --- /dev/null +++ b/megaphone-all_fields.json @@ -0,0 +1,26884 @@ +{ + "Podcasts": [ + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32f", + "Episodes ID": "f6696b28-e328-11ea-91a2-ffdac4384c2d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DeepLearningSystems.mp3", + "Episodes Pubdate Date": "2017-09-19", + "Episodes Summary": "

The applications that demand deep learning range from self-driving cars to healthcare, but the way that models are developed and trained is similar. A model is trained in the cloud and deployed to a device. The device engages with the real world, gathering more data. That data is sent back to the cloud, where it can improve the model.

From the processor level to the software frameworks at the top of the stack, the impact of deep learning is so significant that it is driving changes everywhere. At the hardware level, new chips are being designed to perform the matrix calculations at the heart of a neural net. At the software level, programmers are empowered by new frameworks like Neon and TensorFlow. In between the programmer and the hardware, middleware can transform software models into representations that can execute with better performance.

Milena Marinova is the senior director of AI solutions at the Intel AI products group, and joins the show today to talk about modern applications of machine learning and how those translate into Intel’s business strategy around hardware, software, and cloud. Full disclosure: Intel is a sponsor of Software Engineering Daily.

Question of the Week: What is your favorite continuous delivery or continuous integration tool? Email jeff@softwareengineeringdaily.com and a winner will be chosen at random to receive a Software Engineering Daily hoodie. 

Data Skeptic podcast: Generative Adversarial Networks

", + "Episodes Title": "Deep Learning Systems with Milena Marinova", + "Episodes Uid": "SED1643726884", + "Episodes Audio File": "84aad6b78073525eac5d9fb426009869.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 258, + "Episodes ID": "1694145c-e329-11ea-91a2-8f1658cc8168", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ReactiveStreams_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-08-22", + "Episodes Summary": "

Akka is a toolkit for building concurrent, distributed, message-driven applications on the JVM. Akka provides an implementation of the actor model of concurrency, which simplifies concurrency by adding a lighter weight abstraction than threads and thread pools.
\nKonrad Malawski joins the show today to discuss Akka and reactive streams. Reactive streams is an initiative to provide a standard for asynchronous stream processing. This show goes deep into modern concurrent programming and is a great companion to some of the shows we have done about reactive programming.

", + "Episodes Title": "Akka Reactive Streams with Konrad Malawski", + "Episodes Uid": "SED8083586275", + "Episodes Audio File": "a6518e06c23dfdde323297d57ab23317.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ln", + "Episodes ID": "ee8a4b02-e328-11ea-91a2-e7b3db1ff63b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/podsheets_episode.mp3", + "Episodes Pubdate Date": "2019-04-14", + "Episodes Summary": "Podsheets is a set of open source tools for podcast hosting, publishing, ad management, community engagement, and more. Podsheets is influenced by our experience managing Software Engineering Daily, a full-time podcast business. Software Engineering Daily is a podcast that airs 5 times per week. With 4 ads per show and 50 business weeks per year, we", + "Episodes Title": "Podsheets: Open Source Podcasting", + "Episodes Uid": "SED3140380708", + "Episodes Audio File": "1d69537a36e85d5f26ed7fcb1e0cf23c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1nx", + "Episodes ID": "2255358c-e329-11ea-91a2-3b4bd2a6897f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/lamport_distributed_systems.mp3", + "Episodes Pubdate Date": "2016-02-27", + "Episodes Summary": "

This episode is a republication from my interview with Leslie Lamport on Software Engineering Radio.

Leslie Lamport won a Turing Award in 2013 for his work in distributed and concurrent systems. He also designed the document preparation tool LaTex. Leslie is employed by Microsoft Research, and has recently been working with TLA+, a language that is useful for specifying concurrent systems from a high level.

The interview begins with a definition: a distributed system is a multiprocessor system in which the time required for interprocess communication is large compared to the time for events within a single processor–in other words, it takes longer for interprocess communication than it does for a process to look at its own memory.

Alternatively, a distributed system is one in which processors communicate by sending messages. Leslie goes on to talk about how he became interested in distributed systems, and describes the story behind his paper about the Paxos algorithm. The goal of Paxos is to maintain consensus in an environment with unexpected faults (otherwise known as Byzantine faults). After the discussion of Paxos, Jeff asks Leslie about his recent talk “Thinking for Programmers,” which emphasizes the benefit of having a specification prior to writing actual code. “Specification” can mean a variety of things, but predicates and next-state relationships provide a mathematical rigor that is well-suited to distributed and concurrent systems. The conversation concludes with Jeff asking Leslie about how a programmer can build the mental resolve to work through a difficult problem.

", + "Episodes Title": "Distributed Systems with Leslie Lamport", + "Episodes Uid": "SED7620699909", + "Episodes Audio File": "2d165af170de824e3a0295599c03e49c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24x", + "Episodes ID": "16cb21c2-e329-11ea-91a2-cfeec8757154", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/datavalidation_edited_2.mp3", + "Episodes Pubdate Date": "2016-08-17", + "Episodes Summary": "

Data Validation is the process of ensuring that data is accurate. In many software domains, an application is pulling in large quantities of data from external sources. That data will eventually be exposed to users, and it needs to be correct.
\nRadius Intelligence is a company that aggregates data on small businesses. In order to ensure that business addresses and phone numbers are correct, Radius uses human data validation to ensure that their machine-gathered data is correct. On today’s episode, Srini Kadamati interviews Dan Morris about human data validation, and how it fits into a machine learning pipeline.

", + "Episodes Title": "Data Validation with Dan Morris", + "Episodes Uid": "SED9054121314", + "Episodes Audio File": "395ee84afc1ed5622399f3f071c8f13f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "tk", + "Episodes ID": "2f568470-e329-11ea-91a2-cb59df50a1f7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/leonie_final.mp3", + "Episodes Pubdate Date": "2015-10-16", + "Episodes Summary": "

Léonie Watson is an accessibility engineer and a director at the British Computer Association of the Blind.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

", + "Episodes Title": "Accessibility Engineering with Léonie Watson", + "Episodes Uid": "SED3651265547", + "Episodes Audio File": "8073f47e159db97204a0f8c9ac604f62.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 398, + "Episodes ID": "f575470a-e328-11ea-91a2-2b45bfacfb79", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/BuildingaCloudIBM.mp3", + "Episodes Pubdate Date": "2017-11-29", + "Episodes Summary": "

Cloud computing changed the economics of running a software company.

A cloud is a network of data centers that offers compute resources to developers. In the 1990s, software companies purchased servers–an upfront capital expense that required tens of thousands of dollars. In the early 2000s, cloud computing started, and turned that capital expense into an operational expense.

Instead of a huge bulk purchase of servers, a software developer can pay as they go–which is so much easier on the budget than the bulk purchase. This transformation of capital expense to operational expense significantly lowered the barrier to entry to starting software companies: cloud computing created an economic boom that continues to today, and shows no signs of slowing down.

Of course, the upfront capital expense did not disappear. It got aggregated into the cloud providers. Instead of individual software companies buying servers like they did in the 90’s, cloud providers buy thousands of servers and build data centers around the world. Because the of the aggregation, cloud providers get economies of scale–it is much cheaper for a single cloud provider to buy 1000 servers than for 1000 software companies to buy 1 server.

The first wave of cloud computing was all about deploying our applications to servers that run in cloud data centers. The next wave of cloud computing is moving more and more of our application logic into managed services.

In the first wave of cloud computing, we had to spin up a server to run our database. We needed a server for our search engine, and our load balancer. The logical unit of a server comes with the risk that the server will crash, or will be hacked, or will develop a bug that is difficult to solve.

Managed services abstract away the notion of a server. Database-as-a-service, search-as-a-service, load balancing-as-a-service; these services are reliable lego blocks that we can build entire applications out of. Developers pay a premium for a managed service–but they are happy to pay that premium because it represents a promise that this service will not crash, will not be hacked due to a software vulnerability, and will not develop bugs that are the responsibility of the developer.

Developers are very happy to pay higher unit prices for these managed services than they pay for raw servers. And cloud providers are very happy to develop these managed services–because it turns the infrastructure-as-a-service business into a software-as-a-service business. Software-as-a-service has better margins, better retention, and better competitive differentiation than infrastructure-as-a-service.

As a developer, I’m looking forward to building applications completely out of specialized managed services. But we are still pretty far from that time.

Today, developers still need to write their own application logic and their own backend services. But there are a set of tools that allow developers to write their own services while getting some of the resiliency and scalability of managed services. These tools are functions as a service and Kubernetes.

Functions as a service let developers deploy stateless application logic that is cheap and scalable. Functions as a service still have some problems to overcome in the areas state management, function composition, usability, and developer education.

Kubernetes is a tool for managing containerized infrastructure. Developers put their apps into containers on Kubernetes, and Kubernetes provides a control plane for deployment, scalability, load balancing, and monitoring. So–all of the things that you would want out of a managed service become much easier when you put applications into Kubernetes.

This is why Kubernetes has become so popular–and it is why Kubernetes itself is being offered as a managed service by many cloud providers–including IBM.

For the last decade, IBM has been building out its cloud offerings–and for two of those years, Jason McGee has been CTO of IBM Cloud Platform. In this episode, Jason discusses what it is like to build and manage a cloud, from operations to economics to engineering.

If you like this episode, we have done many other shows about engineering cloud services at Microsoft, Google, Amazon, and Digital Ocean. To find all of our old episodes, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "How IBM Runs Its Cloud with Jason McGee", + "Episodes Uid": "SED4941129083", + "Episodes Audio File": "d0e7066db2615842a1bc119180381ded.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "65c", + "Episodes ID": "ec83e9b2-e328-11ea-91a2-6b1eca3c6677", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_05_MondayEran.mp3", + "Episodes Pubdate Date": "2019-09-05", + "Episodes Summary": "

Modern software is built with cloud services, APIs, and other high level tools. Technical software development is moving beyond the realm of writing code. Individuals who do not have a background in computer science or programming can create increasingly complex tools.

Higher level APIs include Twilio for managing phone communications, and Stripe for managing financial workflows. Platforms such as Shopify can be used as the core system for building an e-commerce business. Low-code tools such as Wix can be used for building web sites.

Monday.com was started in 2012 with the goal of making software for managing business workflows. Business workflows link together different teams and processes within a company. Monday allows non-engineers to automate workflows that are traditionally automated by engineers. For example, Monday can be used to build workflows that link together SalesForce and Twilio, or to trigger actions in MailChimp based on how a user interacted with a Shopify web site.

One of the biggest developing trends in technology is how non-engineers are becoming empowered to have more impact within an organization. The advances in these kinds of tools present us with an opportunity to rethink team structures, and invent entirely new roles for a software company.

Eran Zinman is the CTO and co-founder of Monday.com and he joins the show to describe the vision for Monday and how the product fits into the changing enterprise software trends around APIs and “low code” tools. 

Monday has grown exponentially over the last 7 years, with the most recent growth curve looking almost vertical. Eran’s experience scaling the product and improving performance makes for excellent storytelling. Full disclosure: Monday is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Monday: Business Management Software with Eran Zinman", + "Episodes Uid": "SED8718560715", + "Episodes Audio File": "6f5a91bcc28cbdb7a35861693f592194.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ec", + "Episodes ID": "f4d8d320-e328-11ea-91a2-7f4875f9430a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_13_GravityOfKubernetes.mp3", + "Episodes Pubdate Date": "2018-01-13", + "Episodes Summary": "

Kubernetes has become the standard way of deploying new distributed applications.

Most new internet businesses started in the foreseeable future will leverage Kubernetes (whether they realize it or not). Many old applications are migrating to Kubernetes too.

Before Kubernetes, there was no standardization around a specific distributed systems platform. Just like Linux became the standard server-side operating system for a single node, Kubernetes has become the standard way to orchestrate all of the nodes in your application.

With Kubernetes, distributed systems tools can have network effects. Every time someone builds a new tool for Kubernetes, it makes all the other tools better. And it further cements Kubernetes as the standard.

Google, Microsoft, Amazon, and IBM each have a Kubernetes-as-a-service offering, making it easier to shift infrastructure between the major cloud providers. We are likely to see Digital Ocean, Heroku, and longer tail cloud providers offer a managed, hosted Kubernetes eventually.

In this editorial, I explore the following questions:

Click here to read the full “Gravity of Kubernetes” editorial by Jeff Meyerson.

", + "Episodes Title": "The Gravity of Kubernetes with Jeff Meyerson", + "Episodes Uid": "SED9326634459", + "Episodes Audio File": "45af777d44ea547d35e3c4e68ea890b8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2fx", + "Episodes ID": "093c423e-e329-11ea-91a2-63423c9d8500", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/twilio_1.mp3", + "Episodes Pubdate Date": "2017-01-31", + "Episodes Summary": "

Back in 2008, the range of tools that engineers could use to connect computer systems together were getting quite good. Cloud computing was democratizing access to servers. But the telephony ecosystem was still inaccessible to the average developer. If you needed your program to make a phone call and connect a user to a customer service representative, there was no easy way to do that.

Twilio was started to make it easy for developers to connect to telephone systems using simple API calls. This has unlocked many important use cases: from Uber’s communication systems to the widespread adoption of 2-factor authentication.

In this episode, Twilio VP of product management Pat Malatack joins the show to explain how the company builds and scales the telephony systems that underpin applications which we use every day. We also talked about how Twilio’s culture shapes how engineering proceeds at the company.

Full disclosure: Twilio is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Twilio Engineering with Pat Malatack", + "Episodes Uid": "SED6513754439", + "Episodes Audio File": "777c12a80a2b264ba36b59b8e8fd2e64.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ze", + "Episodes ID": "2bc2b5c2-e329-11ea-91a2-0f7eef3196ff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Codecombat_Edited.mp3", + "Episodes Pubdate Date": "2015-11-19", + "Episodes Summary": "

CodeCombat is a multiplayer live coding strategy game where the players write code to control their characters.

Nick Winter is the CEO and Co-founder of CodeCombat.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "CodeCombat with Nick Winter", + "Episodes Uid": "SED3387841115", + "Episodes Audio File": "96e10c57573900f6109cd4be13444053.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ea", + "Episodes ID": "0aaa95e4-e329-11ea-91a2-af4fca8b2013", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/heartflow_edited_fixed.mp3", + "Episodes Pubdate Date": "2017-01-17", + "Episodes Summary": "

Medical imaging is used to understand what is going on inside the human body and prescribe treatment. With new image processing and machine learning techniques, the traditional medical imaging techniques such as CT scans can be enriched to get a more sophisticated diagnosis.

HeartFlow uses data from a standard CT scan to model a human heart and understand blockages of blood flow using simulations of fluid dynamics. In today’s episode, Razik Yousfi and Leo Grady from HeartFlow describe the data processing pipeline for the company and what their technology stack looks like.

", + "Episodes Title": "Medical Machine Learning with Razik Yousfi and Leo Grady", + "Episodes Uid": "SED1951799116", + "Episodes Audio File": "de43b576e6fb1989a3027cd39c1760e1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3bz", + "Episodes ID": "f51c42c2-e328-11ea-91a2-8bed86c0d6df", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Modern_War.mp3", + "Episodes Pubdate Date": "2017-12-22", + "Episodes Summary": "

Military force is powered by software.

The drones that are used to kill suspected terrorists can identify those terrorists using the same computer vision tools that are used to identify who is in an Instagram picture. Nuclear facilities in Iran were physically disabled by the military-sponsored Stuxnet virus. National intelligence data is collected and processed using the MapReduce algorithm.

The military keeps up with technology more effectively than lawmakers. It is common to read a quote from a senator or a judge that shows a basic misunderstanding of cybersecurity. Many politicians do not even use email.

There is a large and growing knowledge gap between military capability and the technological savvy of policymakers. On the whole, government is not prepared for modern warfare.

We are lucky that military conflict in 2017 is decentralized.

There are small skirmishes in the Middle East, but there is nothing compared to the centralized hostility of World War II. The bonds of international trade form some protection against a war between major powers like US and China.

But it is easy to imagine circumstances that could lead global war. There is an arms race between the United States and China—and this arms race is happening in an environment of increasing informational chaos.
\nThis informational chaos stretches from the highest levels of government to the least informed of our citizenry.

Online journalism is becoming physically dangerous. Journalists are being tracked and threatened. Locations where journalists live have been published by enemies of those journalists. And this war on journalists has a chilling effect on the production of truthful information.

In the war between truth and false information, the people promoting false information have a giant advantage. And that advantage is growing because we cannot identify who is a bot and who is a human.

Social media creates a fog of war around information.

There is also a fog of war around real world physical conflict that is enacted remotely through computers. This type of confusion is the problem known as cybersecurity attribution.

When a power grid gets knocked offline by a hacker, how do we know who was responsible? When a drone flies through New York City shooting at people, how do we know who deployed that drone? When self-driving car technology becomes open source, how long will it be before we see a 9/11-type event performed remotely with cars instead of an airplane—and when it does happen, how will we respond?

Imagine the level of grief and anger on 9/11 that caused our government to launch a war on Iraq. Whether or not you supported that war, we were at least (sort of) aiming in the right direction of the geographic location where the attackers came from.

What would we do if could not figure out who launched such an attack?

When cyber forensics teams look into a problem, it might appear that an attack came from China at one layer, Russia from another layer, and some domestic attacker at another layer. It can be time consuming to uncover the truth behind a cyberattack.

Just like in social media information wars, the instigators of conflict have an advantage.

And the ability to instigate such a conflict is democratized. Social media, open source software, and cloud computing give a technologist superpowers. Cryptocurrencies can anonymize the financial transactions to pay for such tools, and basic encryption can anonymize the terroristic acts that occur over a remote internet connection.

Peter Warren Singer is a political scientist who formerly worked in the United States advisory committee on International Communications and Information Policy. He is also an author, whose books include Wired for War, Cybersecurity and Cyberwar: What Everyone Needs to Know, and Ghost Fleet: A Novel of the Next World War. Peter writes about the circumstances that could lead to global warfare, and how military actors might behave in a third world war.

In this episode, Peter shares a dark, but realistic vision that we should all hope to avoid.

If you like this episode, we have done many other shows on related topics–including drones, IoT security, and automotive cybersecurity. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Modern War with Peter Warren Singer", + "Episodes Uid": "SED5062641606", + "Episodes Audio File": "e2b6f94ad2c3ebecf6ffe5b8f36371dc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ro", + "Episodes ID": "2ff86358-e329-11ea-91a2-5718f272b1d6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/democracyos.mp3", + "Episodes Pubdate Date": "2015-10-09", + "Episodes Summary": "

DemocracyOS is an open-source application for online decision making. The organization’s goal is to enable more responsive and transparent communication with government using modern technology.

Santiago Siri is the president of DemocracyOS.

", + "Episodes Title": "Responsive Government with Santiago Siri", + "Episodes Uid": "SED7111996539", + "Episodes Audio File": "bdb15f9b40416f6700b573eb3415be23.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "20p", + "Episodes ID": "1af75874-e329-11ea-91a2-1322867fe411", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/sre_google_edit3.mp3", + "Episodes Pubdate Date": "2016-06-15", + "Episodes Summary": "

Google’s site reliability engineers are responsible for maintaining the highly available services that power the Google software that we all use on a regular basis. O’Reilly recently published the book “Site Reliability Engineering: How Google Runs Production Systems”, and the book provides a comprehensive window into how the site reliability engineering role works.
\nTodd Underwood is a director of site reliability engineering. On today’s episode, Todd explains how the role of a SRE relates to devops. We discuss the relationship between the engineers who are developing Google services, and the SREs who are maintaining it. Google’s internal data center operating system “Borg” is also discussed.

", + "Episodes Title": "Google’s Site Reliability Engineering with Todd Underwood", + "Episodes Uid": "SED5153637823", + "Episodes Audio File": "f18dec188e418b5c0d3509e92d53d967.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ki", + "Episodes ID": "02238ce6-e329-11ea-91a2-37d89d2f0cec", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/numerai_edited.mp3", + "Episodes Pubdate Date": "2017-04-03", + "Episodes Summary": "

A hedge fund is a collection of investors that make bets on the future. The “hedge” refers to the fact that the investors often try to diversify their strategies so that the direction of their bets are less correlated, and they can be successful in a variety of future scenarios. Engineering-focused hedge funds have used what might be called “machine learning” for a long time to predict what will happen in the future.

Numerai is a hedge fund that crowdsources its investment strategies by allowing anyone to train models against Numerai’s data. A model that succeeds in a simulated environment will be adopted by Numerai and used within its real money portfolio. The engineers who create the models are rewarded in proportion to how well the models perform.

Xander Dunn is a software engineer at Numerai and in this episode he explains what a hedge fund is, why the traditional strategies are not optimal, and how Numerai creates the right incentive structure to crowdsource market intelligence. This interview was fun and thought provoking–Numerai is one of those companies that makes me very excited about the future.

", + "Episodes Title": "Hedge Fund Artificial Intelligence with Xander Dunn", + "Episodes Uid": "SED5139252421", + "Episodes Audio File": "0d91920a6e5472e8f091bfa0cead0040.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2cy", + "Episodes ID": "0e3b5662-e329-11ea-91a2-6b3abd6dc79c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/scaleapi_edited1.mp3", + "Episodes Pubdate Date": "2016-12-16", + "Episodes Summary": "

Some tasks are simple, but cannot be performed by a computer. Audio transcription, image recognition, survey completion–these are simple procedures that almost any human could execute, but the machine learning models have not gotten consistent enough to do them accurately.

Scale is an API for human labor, created by Lucy Guo and Alexandr Wang. Similar to Amazon Mechanical Turk, Scale sends small, simple tasks to workers who can complete those tasks. Scale provides an interface that is easy for developers to use, unlike Mechanical Turk, which requires a dashboard.

Similar to how Stripe allows developers to build software off of payments systems easily, Scale allows developers to build human-driven, manual tasks into their code–which unlocks a wide range of potential applications, which Lucy and Alexandr discussed with me.

", + "Episodes Title": "Scale API with Lucy Guo and Alexandr Wang", + "Episodes Uid": "SED4753366603", + "Episodes Audio File": "5f0d2807ba30da4ec80184d6935a128c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1y6", + "Episodes ID": "1d7f31a2-e329-11ea-91a2-8f2d45d5c0fa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Andreia.mp3", + "Episodes Pubdate Date": "2016-05-05", + "Episodes Summary": "

Virtual reality is a new platform for software engineers to work with. Best practices for VR development have not become widespread throughout the developer community. If you are developing VR software, you need to know how to avoid making the user sick, and this requires an understanding of the hardware limitations.

Andreia Gaita is a software engineer at github. On today’s episode of Software Engineering Daily, Andreia takes us through the developer experience of VR, and gives some analysis and predictions about consumer VR. For anyone who is looking for an introduction to virtual reality development–this episode is for you.

", + "Episodes Title": "Virtual Reality Best Practices with Andreia Gaita", + "Episodes Uid": "SED3355969438", + "Episodes Audio File": "aee2aee820a5cf22f21bb9bec7b48a69.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "go", + "Episodes ID": "34173766-e329-11ea-91a2-ffc45dd5bffa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/adrian_lamo_sed_production.mp3", + "Episodes Pubdate Date": "2015-09-05", + "Episodes Summary": "

Adrián Lamo is a threat analyst, hacker, and writer. In the early 2000’s, Adrián was a hobbyist white-hat hacker, breaking into companies to expose vulnerabilities and fix them.

In 2010, Adrian informed the US Army that Chelsea Manning had provided more than 260,000 documents to Wikileaks.

This interview does not discuss the Manning case, because we covered that topic in our Quoracast interview several months ago.

", + "Episodes Title": "Intelligence and National Security with Adrián Lamo", + "Episodes Uid": "SED4772869992", + "Episodes Audio File": "6e814c8d7f8cfd40254811ebe7dcb53d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "oj", + "Episodes ID": "314b6c8c-e329-11ea-91a2-cf9d97f3ca35", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/stefanie_tellex2.mp3", + "Episodes Pubdate Date": "2015-09-29", + "Episodes Summary": "

Successfully solving a problem often demands a strong model for communication and well-trained robots.

Stefanie Tellex is an assistant professor at Brown University whose research focuses on constructing robots that use natural language to communicate with humans.

", + "Episodes Title": "Robot-Human Interaction with Stefanie Tellex", + "Episodes Uid": "SED2580347870", + "Episodes Audio File": "52e807f62c52db217163dba4d7796fc1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "dw", + "Episodes ID": "3599e05c-e329-11ea-91a2-93de8f1ac510", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/jenkins_kohsuke_kawaguchi.mp3", + "Episodes Pubdate Date": "2015-08-27", + "Episodes Summary": "

Kohsuke Kawaguchi is the primary developer of Jenkins CI and the CTO of CloudBees, a provider of enterprise Jenkins.

", + "Episodes Title": "Continuous Delivery with Jenkins Creator Kohsuke Kawaguchi", + "Episodes Uid": "SED9256955801", + "Episodes Audio File": "8905e45266f3b6af57e1c2f0ba67c7b5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "bs", + "Episodes ID": "365c33c8-e329-11ea-91a2-d7534f57dbd0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ethereum_stephantual.mp3", + "Episodes Pubdate Date": "2015-08-22", + "Episodes Summary": "

Technical and financial criticisms facing Ethereum are as real as those faced by bitcoin. This episode is a departure from Databases Week.

Stephan Tual is CCO of Ethereum and founder of Ursium, a blockchain consulting company.

Thanks to Reddit and Quora for questions.

", + "Episodes Title": "Ethereum Skepticism with Stephan Tual, CCO of Ethereum", + "Episodes Uid": "SED1061645720", + "Episodes Audio File": "a889c593d659972614f4d62ffe59afc2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "oc", + "Episodes ID": "3159cfde-e329-11ea-91a2-732d4c56721b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/bludoors_2.mp3", + "Episodes Pubdate Date": "2015-09-27", + "Episodes Summary": "Crocodile Browser with Anesi and Osine Ikhianosime", + "Episodes Title": "Crocodile Browser with Anesi and Osine Ikhianosime", + "Episodes Uid": "SED1433480714", + "Episodes Audio File": "cd3f9b457ab88c663224c56f32fb2bae.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "kx", + "Episodes ID": "3263ac42-e329-11ea-91a2-1766a703286c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/tadeu_react_native.mp3", + "Episodes Pubdate Date": "2015-09-21", + "Episodes Summary": "

Mobile devices use a virtual machine to interpret the JavaScript into native code.

Tadeu Zagallo is a Facebook engineer who works on React Native for iOS.

", + "Episodes Title": "React Native with Tadeu Zagallo", + "Episodes Uid": "SED2984289756", + "Episodes Audio File": "9ecea0bf024f664c5e597e9d1c003863.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "i1", + "Episodes ID": "33c0e0be-e329-11ea-91a2-e7281008cd80", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/jessica_kerr.mp3", + "Episodes Pubdate Date": "2015-09-09", + "Episodes Summary": "

Scala, Clojure, and Akka are functional tools built on the Java Virtual Machine.

Jessica Kerr is a functional developer on the JVM. She currently works at Monsanto. At QCon San Francisco, she will be giving a talk called Contracts in Clojure: Settling Types vs. Tests.

", + "Episodes Title": "Functional Programming with Jessica Kerr", + "Episodes Uid": "SED5903670318", + "Episodes Audio File": "7079d730cc6e16891870b4e2c44a9466.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2t", + "Episodes ID": "38b154e6-e329-11ea-91a2-ebd8c768b287", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/restify_yunong_2.mp3", + "Episodes Pubdate Date": "2015-07-31", + "Episodes Summary": "

restify is a node.js module built to enable correct REST web services. Netflix uses restify to gain performance and visibility.

Yunong Xiao, senior engineer at Netflix, talks about the incident which incited Netflix’s service migration to restify. The discussion starts with an explanation of flame graphs and evolves into a conversation about restify, and the importance of choosing the correct RESTful API.

Links:

", + "Episodes Title": "restify at Netflix with Yunong Xiao", + "Episodes Uid": "SED9003200924", + "Episodes Audio File": "89edac23b8f22ff7ff8b17deadfef233.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "kg", + "Episodes ID": "32ae284e-e329-11ea-91a2-2bd9d1e5d400", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/dan_abramov.mp3", + "Episodes Pubdate Date": "2015-09-18", + "Episodes Summary": "

Redux is a predictable state container for JavaScript to use with React or any other view library.

Dan Abramov currently works full time on Redux, React Hot Loader, and React Transform.

", + "Episodes Title": "Flux, Redux, and React Hot Loader with Dan Abramov", + "Episodes Uid": "SED3576862911", + "Episodes Audio File": "298afa892229457154df17db290b7e49.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2x3", + "Episodes ID": "f71e49c6-e328-11ea-91a2-6b082f8b6fc4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/MSDevShow.mp3", + "Episodes Pubdate Date": "2017-07-27", + "Episodes Summary": "

A decade ago, a Microsoft developer might have been defined by the fact that they built C# applications on Windows. Today, a Microsoft developer is just as likely to be writing JavaScript for Linux. The company has repositioned itself to focus on cloud services, SaaS products, and enterprise artificial intelligence.

Jason Young and Carl Schweitzer host the MS Dev Show, a popular podcast about Microsoft developers and technologies. On their show, they explore the rapidly expanding marketplace of services on Microsoft Azure and talk to experts about how these services are built and what they are used for.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Microsoft Developers with Jason Young and Carl Schweitzer", + "Episodes Uid": "SED8752294973", + "Episodes Audio File": "120a54c95ce34f8fa4e37c89c9754c02.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2x7", + "Episodes ID": "f70eda04-e328-11ea-91a2-fb31318b3677", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Patents.mp3", + "Episodes Pubdate Date": "2017-08-01", + "Episodes Summary": "

Patents allow individuals and company to lay creative claim for an invention. A patent can provide protection from having its idea being used without giving credit to its creators. Of course, is that patents can be filed and not turned into products, inhibiting innovation. Patents can also be used offensively in a practice known as patent trolling.

Large companies like IBM and Google have so many patents that they have trouble keeping track of them all. And if your company has many different hardware and software products, how can you be sure that your patent collection protects you from a patent troll?

Nicole Shanahan is the CEO of ClearAccessIP, a product that indexes patents, looks for vulnerabilities in a corporation’s patent strategy, and finds opportunities in a patent collection for further value. The large text corpus of a patent collection is the perfect place to apply machine learning.

We discussed the nature of patents, the intersection between law and software, and the product development process of ClearAccessIP.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Patents with Nicole Shanahan", + "Episodes Uid": "SED8706876028", + "Episodes Audio File": "d938188927ab6a63f7e39213a93b5c54.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 667, + "Episodes ID": "ec7a96be-e328-11ea-91a2-671c53ca8c71", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_09_OpenSourceHistorywithBrucePerens.mp3", + "Episodes Pubdate Date": "2019-09-09", + "Episodes Summary": "

Open source plays a key role in today’s world of technology businesses. Today, the impact of open source seems obvious. From Kubernetes to distributed databases to cloud providers, so much of our software is powered by open source. But it was not always this way.  

Bruce Perens was one of the earliest figures in the world of open source. He collaborated with Eric S. Raymond, the author of Cathedral and the Bazaar. He developed a differing belief set from Richard Stallman, who was another foundational advocate of open source. Bruce worked as an engineer at Pixar from 1987 to the year 2000.

Bruce joins the show to give a history of open source and his experience in the software industry.

", + "Episodes Title": "Open Source Policy with Bruce Perens", + "Episodes Uid": "SED3142179617", + "Episodes Audio File": "a9f3397fb8ed3dc54c697792b047db36.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5r8", + "Episodes ID": "edf11cfc-e328-11ea-91a2-7fe980577a3b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_24_CamelCamelCamel.mp3", + "Episodes Pubdate Date": "2019-05-24", + "Episodes Summary": "

CamelCamelCamel is a tool for tracking prices on items on Amazon.com. The company was launched eleven years ago and is built off of the Amazon Product Advertising API. Daniel Green is one of the founders of CamelCamelCamel, and he joins the show to describe his experience building the product.

Amazon and CamelCamelCamel (C3) have a complex relationship. C3 makes its money from referral listings. When a user tracks the price of an Amazon item using C3, that user will probably eventually click on the referral listing on C3. If the user purchases the item on Amazon, C3 gets a percentage of the purchase from Amazon.

C3 has millions of product listings where they are tracking the price of items on Amazon. They have created a directory with a large subset of Amazon’s items by leveraging an API that was originally meant for advertising. Whether or not this is a proper use of the API, C3 arguably leads to more purchasing volume on Amazon–which is ostensibly why Amazon lets the company continue to operate.

In today’s show, Daniel gives a history of CamelCamelCamel, including his own background as an engineer working in finance and how he wound up working on C3 for the past decade. We also talk through how C3 is architected.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "CamelCamelCamel: Amazon Price Tracker with Daniel Green", + "Episodes Uid": "SED6334592979", + "Episodes Audio File": "3050f34db18ba8c022060e6ed2671957.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5gb", + "Episodes ID": "ef09625c-e328-11ea-91a2-e79f32415247", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_12_AdFraudMethod.mp3", + "Episodes Pubdate Date": "2019-03-12", + "Episodes Summary": "

Advertising fraud occurs when a brand pays for an advertisement online and that advertisement is shown to an automated bot account that has been created to view ads. Advertising fraud is rampant on the Internet. It’s not possible to know how much money is lost to ad fraud, but the costs are in the billions of dollars.

Praneet Sharma and Shailin Dhar are the founders of Method Media Intelligence, a company that builds solutions around improving advertising quality. In previous shows, Praneet and Shailin have described the online advertising ecosystem in detail. They have told stories of bot farms, replay attacks, and adtech companies.

In today’s episode, Praneet and Shailin return to the show to discuss how advertising fraud is getting worse–not better. Praneet and Shailin worked with BuzzFeed reporter Craig Silverman, who was a previous guest on the show to talk about his remarkable findings about mobile advertising fraud, which accounts for hundreds of millions of dollars in theft every year.

", + "Episodes Title": "Ad Fraud Engineering with Praneet Sharma and Shailin Dhar", + "Episodes Uid": "SED3889601740", + "Episodes Audio File": "d8704f74b5a5efa62e8ae3beb8fa8a6c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3s3", + "Episodes ID": "f303afb6-e328-11ea-91a2-57c824d12606", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_18_VoiceDesign.mp3", + "Episodes Pubdate Date": "2018-05-18", + "Episodes Summary": "

Voice interfaces are a newer form of communicating with computers. Alexa is a voice interface platform from Amazon. Alexa powers the Amazon Echo, as well as Alexa-enabled cars, refrigerators, and dishwashers. Any developer can build a device with a voice interface using a Raspberry Pi.

Paul Cutsinger works on Echo and Alexa at Amazon. He’s focused on growing the market of developers who are building voice interfaces. In this episode, Paul describes how to design and implement a voice application for the Amazon Alexa platform.

The market for voice powered apps is so new, and there has yet to be a “killer app.” If you like to tinker on new platforms, you will like this episode–and I was surprised by how easy it sounds to build a voice app.

Personally I use voice interfaces all the time–to set timers, to find out how to tell if a cucumber has gone bad, to ask what temperature to cook a potato at. Sometimes, when I am lying in bed trying to get to sleep, I will ask my nearest device to read me a Wikipedia article. These are great use cases, but I’m sure we will see something much more groundbreaking in the future.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Alexa Voice Design with Paul Cutsinger", + "Episodes Uid": "SED2977641791", + "Episodes Audio File": "b995aacfbefdbbba77086b30d5300e80.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 554, + "Episodes ID": "effe83e0-e328-11ea-91a2-3b2474a8be98", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SelfDrivingDeepLearning.mp3", + "Episodes Pubdate Date": "2018-12-27", + "Episodes Summary": "

Originally posted on 28 July 2017.
\n

Self-driving cars are here. Fully autonomous systems like Waymo are being piloted in less complex circumstances. Human-in-the-loop systems like Tesla Autopilot navigate drivers when it is safe to do so, and lets the human take control in ambiguous circumstances.

Computers are great at memorization, but not yet great at reasoning. We cannot enumerate to a computer every single circumstance that a car might find itself in. The computer needs to perceive its surroundings, plan how to take action, execute control over the situation, and respond to changing circumstances inside and outside of the car.

Lex Fridman has worked on autonomous vehicles with companies like Google and Tesla. He recently taught a class on deep learning for semi-autonomous vehicles at MIT, which is freely available online. There was so much ground to cover in this conversation. Most of the conversation was higher level. How do you even approach the problem? What is the hardware and software architecture of a car?

I enjoyed talking to Lex, and if you want to hear more from him check out his podcast Take It Uneasy, which is about jiu jitsu, judo, wrestling, and learning.

", + "Episodes Title": "Self-Driving Deep Learning with Lex Fridman Holiday Repeat", + "Episodes Uid": "SED4860848783", + "Episodes Audio File": "74af0314f9058aedf8c7e21256de91bb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "j6", + "Episodes ID": "33468288-e329-11ea-91a2-73a530aee2b0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/shuman_shape_security.mp3", + "Episodes Pubdate Date": "2015-09-15", + "Episodes Summary": "

Security researchers and organizations have to stay vigilant in this cat-and-mouse game.

Shuman Ghosemajumder is the VP of Product at Shape Security, which defends applications from malware and bots. He is the former click fraud czar at Google, and he will be speaking at QCon San Francisco.

", + "Episodes Title": "Botnets and Cybercrime with Shuman Ghosemajumder", + "Episodes Uid": "SED1831514540", + "Episodes Audio File": "e31dc35ded391a33527b75f2e14193e6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3og", + "Episodes ID": "f37241f6-e328-11ea-91a2-a343d10ef609", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_19_ReactandGraphQL.mp3", + "Episodes Pubdate Date": "2018-04-19", + "Episodes Summary": "

Most new frontend webapps today use ReactJS. An increasing number of mobile apps are created using the cross-platform components of React Native. GraphQL, Facebook’s open source data-fetching middleware tool is being used by more and more companies, who are finding that it simplifies their development.

Facebook’s open source suite of technologies created a new developer ecosystem. There is an increased demand for engineers who know how to build software with React, ReactJS, and GraphQL. This was the reasoning behind Gabe Greenberg starting G2i, a developer marketplace of engineers who write ReactJS, React Native, and GraphQL applications.

In this episode, Gabe, Lee Johnson, and Chris Severns from G2i join the show to discuss React and the other Facebook open source technologies–as well as the ecosystem around them. We explored the architecture of a developer marketplace business, and how to scale a consulting company.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "React Stack with G2i Team", + "Episodes Uid": "SED9534408826", + "Episodes Audio File": "7b0fc567494f25aa6e0197c6c61be077.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "29p", + "Episodes ID": "1181aefc-e329-11ea-91a2-73cb1a279ef3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/julia-language_edited.mp3", + "Episodes Pubdate Date": "2016-11-08", + "Episodes Summary": "

Jeff Bezanson’s university thesis described the motivation for a new programming language. He discussed the shortcomings of “array based programming environments” and his desire to create a more performant language with the best qualities of Lisp, Python, Ruby, Perl, Mathematica, R, and C.

The Julia Language is a high performance language designed to suit technical users that crave the flexibility to pick their own notation. The language has support for a wide variety of operators, allowing scientists to create domain specific equations that can be elegantly expressed as code.

Jeff Bezanson joins the show to discuss his motivations for Julia, and how the language has evolved since he started working on it.

", + "Episodes Title": "Julia Language with Jeff Bezanson", + "Episodes Uid": "SED6174591391", + "Episodes Audio File": "b4adbd38bbfd88a23d56fa9c627f4656.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6gw", + "Episodes ID": "eb6f79a6-e328-11ea-91a2-274d37b7a947", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_07_FutureOfComputing.mp3", + "Episodes Pubdate Date": "2019-11-26", + "Episodes Summary": "

Originally published June 7, 2018

Moore’s Law states that the number of transistors in a dense integrated circuit doubles about every two years. Moore’s Law is less like a “law” and more like an observation or a prediction.

Moore’s Law is ending. We can no longer fit an increasing amount of transistors in the same amount of space with a highly predictable rate. Dennard scaling is also coming to an end. Dennard scaling is the observation that as transistors get smaller, the power density stays constant.

These changes in hardware trends have downstream effects for software engineers. Most importantly–power consumption becomes much more important.

As a software engineer, how does power consumption affect you? It means that inefficient software will either run more slowly or cost more money relative to our expectations in the past. Whereas software engineers writing code 15 years ago could comfortably project that their code would get significantly cheaper to run over time due to hardware advances, the story is more complicated today.

Why is Moore’s Law ending? And what kinds of predictable advances in technology can we still expect?

John Hennessy is the chairman of Alphabet. In 2017, he won a Turing award (along with David Patterson) for his work on the RISC (Reduced Instruction Set Compiler) architecture. From 2000 to 2016, he was the president of Stanford University.

John joins the show to explore the future of computing. While we may not have the predictable benefits of Moore’s Law and Dennard scaling, we now have machine learning. It is hard to plot the advances of machine learning on any one chart (as we explored in a recent episode with OpenAI). But we can say empirically that machine learning is working quite well in production.

If machine learning offers us such strong advances in computing, how can we change our hardware design process to make machine learning more efficient?

As machine learning training workloads eat up more resources in a data center, engineers are developing domain specific chips which are optimized for those machine learning workloads. The Tensor Processing Unit (TPU) from Google is one such example. John mentioned that chips could become even more specialized within the domain of machine learning. You could imagine a chip that is specifically designed for a LSTM machine learning model.

There are other domains where we could see specialized chips–drones, self-driving cars, wearable computers. In this episode, John describes his perspective on the future of computing, and offers some framework for how engineers can adapt to that future.

", + "Episodes Title": "Future of Computing with John Hennessy Holiday Repeat", + "Episodes Uid": "SED6915237341", + "Episodes Audio File": "dd1a9311e217cacc7df3a32175e8f6ef.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "39r", + "Episodes ID": "f56aaa2a-e328-11ea-91a2-3b363d98b051", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/AnimatingVueJS.mp3", + "Episodes Pubdate Date": "2017-12-01", + "Episodes Summary": "

Most user interfaces that we interact with are not animated. We click on a button, and a form blinks into view. We click a link and the page abruptly changes.

On the other hand, when we interact with an application that has animations, we can feel the difference. The animations are often subtle. If you aren’t sure what I’m talking about, pay attention the next time you use Slack or Facebook Messenger or iMessage. Airbnb values animation so much that they built Lottie, a library for animation.

In an animated application, the user interface feels alive. When a software team takes the time to build animations into small interactions, the user perceives the animations as polish and attention to detail.

Sarah Drasner has been evangelizing the value of animations for years, and she is an expert at implementing complex and beautiful animations on the web. She works at Microsoft as a developer advocate and joins the show to talk about how to build animations. If you are building a web application and want to create a unique UI, you might find this show useful.

JavaScript supports detailed animations, often through the manipulation of SVG files. SVG stands for “scalable vector graphics” a file format that represents an image in its own DOM. SVG is so flexible because of this DOM format, which defines the different parts of the SVG. This is in contrast to a bitmap, which is just a simple matrix of dots, without any rich metadata.

You could manipulate SVG with raw JavaScript—but most people use a frontend JavaScript framework like React, Angular, or VueJS. Sarah has been implementing most of her recent web animations using Vue, and she is a member of the Vue core team.

Vue has an entertaining story, because it gained popularity in a time when Google was supporting AngularJS and Facebook was supporting ReactJS. The first version of Vue was created from scratch by a single developer, Evan You.

If you are a Vue developer looking for an open source project to hack on, you can check out softwaredaily.com, which is an open source platform to consume content about software. In addition to the Vue web app, we also have the Software Engineering Daily app for iOS and for Android. All of these apps are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Animating VueJS with Sarah Drasner", + "Episodes Uid": "SED1131121003", + "Episodes Audio File": "f7d2c085b373ac1d9f64d386b12ff903.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5bv", + "Episodes ID": "ef65553a-e328-11ea-91a2-6f60c681621c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_13_Replicated.mp3", + "Episodes Pubdate Date": "2019-02-13", + "Episodes Summary": "

Cloud computing has been popular for less than twenty years. Large software companies have existed for much longer. If your company was started before the cloud became popular, you probably have a large, data center on your companies premises. The shorthand term for this software environment is “on-prem”.

Deploying software to your own on-prem servers can be significantly different than deploying to remote servers in the cloud. In the cloud, servers and resources are more standardized. It is often easier to find documentation and best practices for how to use cloud services.

Many of the software vendors who got started in the last decade created their software in the cloud. For example, Readme.io makes it easy for companies to create hosted documentation. Their early customers were startups and other cloud-native companies. All of those companies were happy to consume the software in the cloud. As time went on, Readme found that other customers wanted to use the Readme product as a self-hosted, on-prem service. Readme needed to figure out how to deploy their software easily to the “on-prem” environment.

It turns out that this is a common problem. Software vendors who want to sell to on-prem enterprises must have a defined strategy for making those deployments to on-prem infrastructure–and those deployments are not always easy to configure.

Replicated is a company that allows cloud-based software to easily deploy to on-prem infrastructure. Grant Miller is the founder of Replicated and he joins the show to discuss on-prem, cloud, and the changing adoption patterns of enterprise software companies.

", + "Episodes Title": "Replicated: On-Prem Deployments with Grant Miller", + "Episodes Uid": "SED4312323079", + "Episodes Audio File": "255681d2cf14253fe0ed05534950652b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5s3", + "Episodes ID": "edd689f0-e328-11ea-91a2-eb62df87f6d5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_03_Anthos.mp3", + "Episodes Pubdate Date": "2019-06-03", + "Episodes Summary": "

Google’s cloud business was long regarded as a place where startups could build a business, but not established enterprises. For serious workloads, enterprises chose Amazon almost unanimously. This phenomenon of Amazon as the default was described by a phrase that harkened back to the days of IBM’s dominance: “nobody ever got fired for choosing AWS.”

With the rise of Kubernetes, Google has established a reputation as a reliable provider of container orchestration. As enterprises look to roll out Kubernetes workloads, Google is convincing many of them to work with Google Kubernetes Engine.

Kubernetes is one part of the changes which fall under the description of “digital transformation”. As these enterprises build out their digital transformation strategy, they are also looking for a strategy around multicloud, on-prem, policy management, and consulting partnerships.

Anthos is a platform where enterprises manage the resources and configuration of their cloud deployments, as well as a system to partner with services integrators and independent software vendors.

Aparna Sinha works on Anthos, Google Kubernetes Engine, and other projects at Google. In today’s show we discuss the process of digital transformation, as well as the tactics for how a digital transformation is actually implemented. We also talked about GKE on-prem, and the kinds of tooling needed by on-prem application deployments.

", + "Episodes Title": "Google Anthos with Aparna Sinha", + "Episodes Uid": "SED2019495684", + "Episodes Audio File": "022433624207f17eb56807bdbd2d45d5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48p", + "Episodes ID": "f1b3c498-e328-11ea-91a2-c77ef617f85e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_16_DoordashEngineering.mp3", + "Episodes Pubdate Date": "2018-08-16", + "Episodes Summary": "

DoorDash is a logistics company that connects customers, restaurants, and drivers that can move food to its destination. When a customer orders from a restaurant, DoorDash needs to identify the ideal driver for picking up the order from the restaurant and dropping it off with the customer.

This process of matching an order to a driver takes in many different factors. Let’s say I order spaghetti from an Italian restaurant. How long does the spaghetti take to prepare? How much traffic is there in different areas of the city? Who are the different drivers who could potentially pick the spaghetti up? Are there other orders near the Italian restaurant, that we could co-schedule the spaghetti delivery with?

In order to perform this matching of drivers and orders, DoorDash builds machine learning models that take into account historical data. In today’s episode, Raghav Ramesh explains how DoorDash’s data platform works, and how that data is used to build machine learning models. We also explore the machine learning model release process—which involves backtesting, shadowing, and gradual rollout.

", + "Episodes Title": "DoorDash Engineering with Raghav Ramesh", + "Episodes Uid": "SED1408012906", + "Episodes Audio File": "631bf5229ea64e911d2284ff9134095d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3nj", + "Episodes ID": "f393cfce-e328-11ea-91a2-5713b7663c30", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_10_DatabaseChaosEngineering.mp3", + "Episodes Pubdate Date": "2018-04-10", + "Episodes Summary": "

Tammy Butow has worked at Digital Ocean and Dropbox, where she built out infrastructure and managed engineering teams. At both of these companies, the customer base was at a massive scale.

At Dropbox, Tammy worked on the database that holds metadata used by Dropbox users to access their files. To call this metadata system simply a “database” is an understatement–it is actually a multi-tiered system of caches and databases. This metadata is extremely sensitive–this is metadata that tells you where the objects across Dropbox are located–so it has to be highly available.

To encourage that reliability, Tammy helped institute chaos engineering–inducing random failures across the Dropbox infrastructure, and making sure that the Dropbox systems could automatically respond to those failures. If you are unfamiliar with the topic, we have covered chaos engineering in two previous episodes of Software Engineering Daily.

Tammy now works at Gremlin, a company that does chaos engineering as a service. In this show we talked about her experiences at Dropbox, and how to institute chaos engineering across databases. We also explored how her work at Gremlin–a smaller startup–compares to Dropbox and Digital Ocean, which are larger companies.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Database Chaos with Tammy Butow", + "Episodes Uid": "SED7284225492", + "Episodes Audio File": "5cd2481581ae61f0fe57eeda8ec37671.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5u2", + "Episodes ID": "edabb11c-e328-11ea-91a2-cf6447f40c23", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_14_ElegantPuzzle.mp3", + "Episodes Pubdate Date": "2019-06-14", + "Episodes Summary": "

Software engineering is an art and a science. To manage engineers is to manage artists and scientists.

Software companies build practical tools like payment systems, messaging products, and search engines. Software tools are the underpinnings of our modern lives. You might expect this core infrastructure which modern humans rely on to have been constructed with pure formulaic rigor.

But the best software tools are not built within a totally defined process. Software is built through messy iteration. When a piece of software looks pristine, that is often a function of how many mistakes have been made, and then subsequently corrected for.

There is no fixed process for how to build good software.

As our tools get better, we have to update our software engineering practices to utilize those new tools. We have to rethink the style that we are working in. We have to discard old tools and procedures in order to pick up the new ones, and have higher leverage.

As an organization scales, the structure of the organization needs to be modified. Team members need to be reallocated. Checks and balances need to be put in place. Rules and cultural practices need to codified, because a larger organization cannot have ties broken by an individual.

Software is built by humans, and every management decision must be considered in the light of human psychology. When we change a line of code, the code does not get emotional about being altered. But the same cannot be said of humans. Even a minor conversation between an engineering manager and a direct report can have lasting implications.

Will Larson is the author of An Elegant Puzzle: Systems of Engineering Management. He works on Foundation Engineering at Stripe, and has worked in engineering management at Uber, Digg, and other software companies. Elegant Puzzle provides strategies, tactics, and ruminations on software development. Will joins the show to explore the multifaceted subject of engineering management.

", + "Episodes Title": "Elegant Puzzle with Will Larson", + "Episodes Uid": "SED7580584584", + "Episodes Audio File": "21b292837d60068dccf10922875031af.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3zu", + "Episodes ID": "f2a0f4ca-e328-11ea-91a2-234a60603a40", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_15_DigitalEvolution.mp3", + "Episodes Pubdate Date": "2018-06-15", + "Episodes Summary": "

Evolutionary algorithms can generate surprising, effective solutions to our problems.

Evolutionary algorithms are often let loose within a simulated environment. The algorithm is given a function to optimize for, and the engineers expect that algorithm to evolve a solution that optimizes for the objective function given the constraints of the simulated environment. But sometimes these results are not exactly what we are looking for.

For example, imagine an evolutionary algorithm that tries to evolve a creature that do a flip within a simulated physics engine that mirrors the real world.

You could imagine all sorts of evolutionary traits. Maybe the creature will evolve to have legs that are like springs, and let the creature jump high enough to do a flip. Maybe the creature will develop normal legs with strong muscles that propel the creature high enough to flip. But you wouldn’t expect the creature to evolve to be extremely tall–so tall that the creature can merely lean over fast enough so that the top of its body flips upside down. In one experiment, this is exactly what happened.

In another, similar experiment, the evolving creature discovered a bug in the physics engine of the simulated environment. This creature was able to exploit the problem with this physics engine to be able to move in ways that would not be possible in our real-world physical universe.

Evolutionary algorithms sometimes evolve solutions in ways that we don’t expect. Researchers usually throw those results away, because they don’t contribute to the result that the researchers are looking for. The consequence is that lots of interesting anecdotes get lost.

Joel Lehman, Dusan Misevic, and Jeff Clune are the lead authors of the paper “The Surprising Creativity of Digital Evolution.” The paper was a collection of anecdotes about strange results within the world of digital evolution. They join the show to describe what digital evolution is, and some of the strange results that they surveyed in their paper.

Joel and Jeff are engineers at Uber’s artificial intelligence division–so this topic has applicable importance to them. Machine learning is all about evolution within simulated environments, and developing safe algorithms for AI requires an understanding of what can go wrong in a poorly defined evolutionary system.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Digital Evolution with Joel Lehman, Dusan Misevic, and Jeff Clune", + "Episodes Uid": "SED6397999506", + "Episodes Audio File": "3365ee4455b14485b244ebbbb60c8576.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5fh", + "Episodes ID": "ef1bdbda-e328-11ea-91a2-379d975e0459", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_06_Wasmer.mp3", + "Episodes Pubdate Date": "2019-03-06", + "Episodes Summary": "

WebAssembly is a runtime that lets languages beyond JavaScript to execute in frontend web applications. WebAssembly is novel because most modern frontend applications are written entirely in JavaScript. WebAssembly lets us use languages like Rust and C++ after they have been compiled down to a web assembly binary module.

Language interoperability is only one part of why WebAssembly is exciting. The execution environment for WebAssembly modules has benefits for security and software distribution and consumption as well.

In previous shows, we’ve given an overview of WebAssembly and explored its future applications as well as its relationship to the Rust programming language. In today’s episode, we explore the packaging and execution path of a WebAssembly module, and some other applications of the technology.

Syrus Akbary is the CEO and founder of Wasmer, a company focused on creating universal binaries powered by WebAssembly. Wasmer provides a way to execute WebAssembly files universally. He joins the show to talk about the state of WebAssembly, and what his company is building.

", + "Episodes Title": "WebAssembly Execution with Syrus Akbary", + "Episodes Uid": "SED1648386403", + "Episodes Audio File": "5d1590fc0422c20492504f148aedfe73.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ru", + "Episodes ID": "fa0e97b2-e328-11ea-91a2-cfbc970bfc2d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/dns_edited.mp3", + "Episodes Pubdate Date": "2017-06-06", + "Episodes Summary": "

DNS stands for domain name system. This is the naming system that maps the entire internet. It associates information with domain names. More specifically, DNS specifies mappings between numerical IP addresses and domain names.

Most engineers know these basic facts about DNS, but they may not know how much engineering a complex company like Etsy or Zappos puts into their DNS configuration. Dynamic DNS allows for intelligent response, so that a resource is served from the most efficient place–even in the face of a DDoS attack, or just routine failure of cloud servers.

Phil Stanhope is the VP of technology at Oracle Dyn and he joins the show to explain how modern DNS works and the role of a DNS provider. Full disclosure: Dyn is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "DNS with Phil Stanhope", + "Episodes Uid": "SED3936422948", + "Episodes Audio File": "ff1d3bde34da404faf7ca91eabca2c46.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ox", + "Episodes ID": "fc89e64a-e328-11ea-91a2-1fff20601a33", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/crispr_edited.mp3", + "Episodes Pubdate Date": "2017-05-05", + "Episodes Summary": "

CRISPR is a technique for altering the human genome. It might be the most powerful tool for biological modification that we have ever discovered. In this episode, we explore CRISPR: how it works, why it exists in the natural world, and the implications for being able to modify DNA so easily.

Geoff Ralston is a partner at Y-Combinator. He wrote an article entitled Hacking DNA: The Story of CRISPR, Ken Thompson, and the Gene Drive. Since Geoff is not a biologist, he is the perfect person to explain CRISPR to an audience of non-biologists.

Since he is an investor, he is also great at explaining the pace at which CRISPR might make it to market, and how it might converge with some of the other futuristic trends we are seeing so regularly today.

If you are interested in hosting a show for Software Engineering Daily, we are looking for engineers, journalists, and hackers who want to work with us on content. It is a paid opportunity. Go to softwareengineeringdaily.com/host to find out more.

The Software Engineering Daily store is now open if you want to buy a Software Engineering Daily branded t-shirt, hoodie, or mug and support the show. Go to softwareengineeringdaily.com/store.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "CRISPR with Geoff Ralston", + "Episodes Uid": "SED6200937467", + "Episodes Audio File": "15e8f39dadaacee0ea57a47946b7aab5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 382, + "Episodes ID": "f59d5a92-e328-11ea-91a2-e388d50ddb18", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/FiverrEngineering.mp3", + "Episodes Pubdate Date": "2017-11-15", + "Episodes Summary": "

As the gig economy grows, that growth necessitates innovations in the online infrastructure powering these new labor markets.

In our previous episodes about Uber, we explored the systems that balance server load and gather geospacial data. In our coverage of Lyft, we studied Envoy, the service proxy that standardizes communications and load balancing among services. In shows about Airbnb, we talked about the data engineering pipeline that powers economic calculations, user studies, and everything else that requires a MapReduce.

In today’s episode, we explore the business and engineering behind another online labor platform: Fiverr.

Fiverr is a marketplace for digital services. On Fiverr, I have purchased podcast editing, logo creation, music lyrics, videos, and sales leads. I have found people who will work for cheap, and quickly finish a job to my exact specification. I have discovered visual artists who worked with me to craft a music video for a song I wrote.

Workers on Fiverr post “gigs”–jobs that they can perform. Most of the workers on Fiverr specialize in knowledge work, like proofreading or gathering sales leads. The workers are all over the world. I have worked with people from Germany, the Philippines, and Africa through Fiverr.

Fiverr has become the leader in digital freelancing. The staggering growth of Fiverr’s marketplace has put the company in a position similar to an early Amazon. There is room for strategic expansion, but there is also an urgency to improve the infrastructure and secure the market lead.

Gil Scheinfeld is the CTO at Fiverr, and he joins the show to explain how the teams at Fiverr are organized to fulfill the two goals of strategic, creative growth and continuous improvement to the platform.

One engineering topic we discussed at length was event sourcing. Event sourcing is a pattern for modeling each change to your application as an event. Each event is placed on a pub/sub messaging queue, and made available to the different systems within your company. Event sourcing creates a centralized place to listen to all of the changes that are occurring within your company.

For example, you might be working on a service that allows a customer to make a payment to a worker. The payment becomes an event. Several different systems might want to listen for that event. Fiverr needs to call out to a credit card processing system. Fiverr also needs to send an email to the worker, to let them know they have been paid. Fiverr ALSO needs to update internal accounting records.

Event sourcing is useful because the creator of the event is decoupled from all of the downstream consumers. As the platform engineering team works to build out event sourcing, communications between different service owners will become more efficient.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Fiverr Engineering with Gil Scheinfeld", + "Episodes Uid": "SED8591572387", + "Episodes Audio File": "8fe55368352b1098012dd35841337305.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ca", + "Episodes ID": "ef5c9e86-e328-11ea-91a2-4b38f227c407", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_15_Ethsimple.mp3", + "Episodes Pubdate Date": "2019-02-15", + "Episodes Summary": "

Ethereum allows developers to run decentralized applications. But the tooling for building and managing those decentralized applications is immature. Experienced software engineers have difficulty getting started with writing Ethereum applications because the stack of tools is so unfamiliar and different than traditional software tools.

Whether or not Ethereum itself succeeds, developers in the future will probably be building some decentralized apps. We will be treating money as a first-class citizen and architecting software that transfers financial value as easily as we transmit JavaScript today. “Web3” will be a world in which many more software applications will be possible.

As we move towards Web3, many new tools will be built. Web2 was the result of Ruby on Rails, Amazon Web Services, the iPhone, and other software tools that made it easier to deploy web servers and consume Internet services. In the world of Web2, we saw the birth of Airbnb, Uber, and Netflix. In the world of Web3, we will see new types of gig economy apps, sharing economy platforms, and social networks. These new applications will arrive gradually as the tooling improves, and makes it easier for developers to hack together businesses and side projects built on cryptocurrencies.

Brian Soule is the founder or Ethsimple, a company that makes tools for Ethereum developers. Brian joins the show to talk about the state of cryptocurrencies, the tooling that developers have access to, and his company Ethsimple.

We cover high-level ideas, such as Bitcoin maximalism and also talk about some more technical areas of the Ethereum ecosystem, such as the Ethereum Name Service.

", + "Episodes Title": "Ethsimple: Ethereum Tools with Brian Soule", + "Episodes Uid": "SED9864209741", + "Episodes Audio File": "274457eae7783cf5323722f4c690ebbf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "29g", + "Episodes ID": "11d349a6-e329-11ea-91a2-9bfeb78534cb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/chatops_edited.mp3", + "Episodes Pubdate Date": "2016-11-02", + "Episodes Summary": "

Chat bots are your newest co-worker. Slack, HipChat, and other chat clients allow developers and other team members to communicate more dynamically than the limits of email. Companies have started to add bots to their chat rooms. These bots can give you technical information, restart a server, or notify you that a build has finished.

Jason Hand is the author of ChatOps: Managing Infrastructure in Group Chat. He joins the show today to discuss how ChatOps improves development and operations by centralizing lots of functionality in group chat. Edaena Salinas is the host for today’s show. She also hosts the excellent Women In Tech Show–a podcast we highly recommend.

Since we are on the subject of bots–we want to thank O’Reilly Media for recently providing Software Engineering Daily a ticket to Bot Day.

", + "Episodes Title": "ChatOps with Jason Hand", + "Episodes Uid": "SED8750263488", + "Episodes Audio File": "9e31dee71fb43275fde3cc609a3f8efb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3pq", + "Episodes ID": "f3323462-e328-11ea-91a2-7397f7b9d45e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_05_RoboticWheel_InfrastructureatHubspotMeetupTalks.mp3", + "Episodes Pubdate Date": "2018-05-05", + "Episodes Summary": "

Superpedestrian is a robotic bicycle wheel that learns how you pedal and personalizes your bicycle ride. The engineering challenges of Superpedestrian are at the intersection of robotics, software, and real-time analytics. The first half of today’s show is about Superpedestrian. Goss Nuzzo Jones and Matt Cole are engineers at Superpedestrian. The slides for their presentation are also in the show notes.

The second half of today’s show is about HubSpot, a massive business with lots of infrastructure challenges. Thomas Petr explained how HubSpot’s engineering has matured, and some of the scaling problems they have tackled.

Last month, we had three Software Engineering Daily Meetups: in New York, Boston, and Los Angeles. At each of these Meetups, listeners from the SE Daily community got to meet each other and talk about software–what they are building and what they are excited about. I was happy to be in attendance at each of these, and I am posting the talks given by our presenters. The audio quality is not perfect on these, but there are also no ads.

Thank you to HubSpot for hosting this Meetup–they have beautiful offices and if you are looking for a job (or if you want to host a technology Meetup in the Boston area) I strongly recommend checking them out.

We’d love to have you as part of our community. We will have more Meetups eventually, and you can be notified of these by signing up for our newsletter. Come to SoftwareDaily.com and get involved with the discussion of episodes and software projects. You can also check out our open source projects–the mobile apps, and our website.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Superpedestrian Robotic Wheel / Infrastructure at HubSpot Meetup Talks", + "Episodes Uid": "SED4393776526", + "Episodes Audio File": "9adfd35a76f4326c9f5a2ce16120844f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 321, + "Episodes ID": "f67c2920-e328-11ea-91a2-131770d13195", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/GeorgeAnders.mp3", + "Episodes Pubdate Date": "2017-09-14", + "Episodes Summary": "

Software gives us new ways of communicating with each other. Engineers build scalable systems for e-commerce, helpdesk, and video sharing–and these systems do scale, to millions of people. But software alone cannot serve all of the demands of all the users and customers on these platforms.

We need customer service representatives to address unexpected demands. We need design specialists to evaluate the interface that made sense to the engineers but not the users. We need sales people to connect our strange software to an impatient prospective customer.

Engineers sometimes joke about firing all the non-engineers in the company. As engineers, it is easy to discount all of the work that non-engineers do–it can seem unscalable, or non-quantifiable, or mechanical. But most companies would fall over immediately without support, sales, design, operations, and the multitude of other non-engineering roles.

More to the point–people in non-technical roles can drive the success of an en organization. Some of the most influential leaders in tech came from a non-technical background: Stuart Butterfield of Slack; Brian Chesky of Airbnb; Sheryl Sandberg of Google and Facebook. A liberal arts education can foster the perfect set of skills to thrive in a technology company.

George Anders is an author whose most recent book is called You Can Do Anything: The Surprising Power of a “Useless” Liberal Arts Education. George is one of my favorite business writers, and some of his past writing includes pieces about Sequoia Capital, Amazon, Linkedin, and a ton of other topics on Quora.

If you like this episode, we have done many other shows about business with guests like Seth Godin and Tyler Cowen–indeed many of the shows on Software Engineering Daily are not deeply technical. You can check out our back catalog by downloading the Software Engineering Daily app for iOS, where you can listen to all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that.

", + "Episodes Title": "Doing Anything with George Anders", + "Episodes Uid": "SED7730185750", + "Episodes Audio File": "adbeef1236bbb6eb388cbd42ff81f3da.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4tt", + "Episodes ID": "f0c61c52-e328-11ea-91a2-b767b1a35022", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_29_HiringProcess.mp3", + "Episodes Pubdate Date": "2018-10-29", + "Episodes Summary": "

Engineers who start companies often find themselves building something they have no experience with: a hiring process.

Hiring engineers today is not as systematic as building software. We don’t have lots of data that tells us what makes for an effective programming interview question. The smartest tech companies in the world are still making hiring mistakes–often through the “false negative” of rejecting candidates who did not do well in their interview process or through the “false positive” of hiring candidates who did well in the interview, but were not a good fit for the job.

If you are a hiring manager or a company founder, you will eventually have to build a hiring process. If you don’t treat that hiring process scientifically, you will likely make some mistakes.

Ammon Bartram has conducted more than 1000 interviews with engineers, accumulating a vast amount of data. This data was gathered deliberately and scientifically, through closely tracked interview questions and a consistent end-to-end process for the job candidate. Ammon joins the show to talk about the data set he has accumulated, the conclusions from all of these interviews, and how engineering organizations can use this data to develop a smart, data-driven hiring process.

Ammon is co-founder of Triplebyte, a company that helps match engineers and tech companies. Triplebyte also publishes lots of research and blog articles about conducting good interviews, developer salaries, and bootcamps vs. computer science degrees. Full disclosure: Triplebyte is a sponsor of Software Engineering Daily. (However, Ammon has been a guest several times before on the show, since before Triplebyte was a sponsor, and I always enjoy getting to talk to him.)

", + "Episodes Title": "Building a Hiring Process with Ammon Bartram", + "Episodes Uid": "SED6083471141", + "Episodes Audio File": "229b516b1a7b3477221f7a970115fca8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 559, + "Episodes ID": "eff58b46-e328-11ea-91a2-a7749fa55bc0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_02_Upbound.mp3", + "Episodes Pubdate Date": "2019-01-02", + "Episodes Summary": "

Cloud providers created the ability for developers to easily deploy their applications to servers on data centers. In the early days of the cloud, most of the code that a developer wrote for their application could run on any cloud provider, whether it was Amazon, Google, or Microsoft. These cloud providers were giving developers the same Linux server that they would expect from an on-premise deployment.

Early cloud applications such as Netflix, Airbnb, and Uber took advantage of this cloud infrastructure to quickly scale their businesses. In the process, these companies had to figure out how to manage open source distributed systems tools such as Hadoop and Kafka. Cloud servers were easy to create, but orchestrating them together to build distributed systems was still very hard.

As the cloud providers matured, they developed higher level systems that solved many of the painful infrastructure problems. Managed databases, autoscaling queueing systems, machine learning APIs, and hundreds of other tools. Examples include Amazon Kinesis and Google BigQuery. These tools are invaluable because they allow a developer to quickly build applications on top of durable, resilient cloud infrastructure.

With all of these managed services, developers are spending less time on infrastructure and more time on business logic. But managed services also lead to a new infrastructure problem—how do you manage resources across multiple clouds?

A bucket storage system like Amazon S3 has different APIs than Google Cloud Storage. Google Cloud PubSub has different APIs than Amazon Kinesis. Since different clouds have different APIs, developers have trouble connecting cloud resources together, and it has become difficult to migrate your entire application from one cloud provider to another.

Crossplane is an open source control plane for managing resources across multiple clouds. Crossplane’s goal is to provide a single API surface for interfacing with all the parts of your application, regardless of what cloud they are on.

Crossplane is a project that was started by Upbound, a company with the goal of making multicloud software development easier. Bassam Tabbara is the CEO of Upbound, and he joins the show to talk about multi cloud deployments, Kubernetes federation, and his strategy for building a multi cloud API.

", + "Episodes Title": "Crossplane: Multicloud Control Plane with Bassam Tabbara", + "Episodes Uid": "SED1493414810", + "Episodes Audio File": "ab8d91b8dd1b33ae27ed5649175260dd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5a3", + "Episodes ID": "ef9824d8-e328-11ea-91a2-2308182db6e8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_30_MikeSolanaAoN.mp3", + "Episodes Pubdate Date": "2019-01-30", + "Episodes Summary": "

Mars is a cold, inhospitable planet far from earth. It presents one of the most complex challenges faced by engineers: how can we create a new world?

To create a new world, first we have to get there. We can build new rockets with improved propulsion systems. We can build ships that allow us to survive the long, grueling trip from Earth to Mars. We can build robots that will help us construct our new home. And this is just the beginning. Mars could be warmed, and could develop a hydrologic cycle like the system of clouds and oceans on earth. Mars could be a place for new ideas and new cultures, unfettered by the conventions of Earth.

Mike Solana is the host of Anatomy of Next, a podcast about technologies and philosophies of the future. He’s also a vice president at Founder’s Fund. In a previous episode, Mike joined the show to talk about artificial intelligence, genetics, and robotics. Today, we discuss Mars.

The latest season of Anatomy of Next explores the science that is bringing us closer to exploring other planets. On his podcast, Mike speaks with engineers, researchers, and entrepreneurs about the state of the art of space technology–as well as the challenges that remain unsolved.

Mike returns to the show to discuss this dream of a new world. Why should we go to Mars? And why should the software engineers listening to this podcast even care?

To find all 900 of our old episodes, including past episodes with venture capitalists, futurists, and philosophers, check out the Software Engineering Daily app in the iOS and Android app stores. Whether or not you are a software engineer, we have lots of content about technology, business, and culture. In our app, you can also become a paid subscriber and get ad-free episodes–and you can have conversations with other members of the Software Engineering Daily community.

", + "Episodes Title": "Anatomy of Next: New World with Mike Solana", + "Episodes Uid": "SED4133960772", + "Episodes Audio File": "67d790bb4277e1b22c40a6bc7cd661d8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5iz", + "Episodes ID": "eeb531e6-e328-11ea-91a2-133c4009fa4f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_01_Blitzscaling.mp3", + "Episodes Pubdate Date": "2019-04-02", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Chris Yeh is an entrepreneur, investor, and author. He co-wrote Blitzscaling with LinkedIn founder Reid Hoffman.  

Blitzscaling is a strategy for growing a company that has found product market fit. Blitzscaling prioritizes speed over efficiency, arguing that fast growth is necessary to achieve “first scaler advantage.” When a company is the first to scale successfully within a large market, that company gains access to a wealth of market opportunities that are not available to companies which are not at scale.

Examples of successful Blitzscalers include Airbnb, LinkedIn, Amazon, and Facebook. In the hypergrowth phases of these companies, there were deliberate strategic tradeoffs that caused the company to suffer in the short term in exchange for the chance at market dominance in the long term.

Blitzscaling is a broad strategic concept which manifests differently in different companies.

When Airbnb was in its early stages of growth in 2011, the company was faced with the existential threat of a European competitor called Wimdu. Wimdu offered to sell to Airbnb, but this would have required the merger of two companies with distinctly different cultures. Instead, Airbnb chose to raise more money and rapidly expand into Europe.

In contrast, Google’s rapid path to becoming a dominant information service involved acquisitions that we now see as key Google products, including Android, Google Maps, and Google Earth.

Through numerous examples in recent business history, Blitzscaling explores the fundamental tradeoff between speed and efficiency, usually biasing speed as the preferable element. But Blitzscaling does not work for every company.

In the food delivery sector, many companies who tried to blitzscale ended up going out of business because they had lowered their prices too much in order to try to earn customer loyalty. By lowering their prices too much, food delivery startups built businesses with fundamentally bad unit economics and a fickle customer base.

In other cases, aggressive blitzscaling can work for a short period of time, but can cause a company’s culture to suffer in ways that are very hard to repair. Blitzscaling can also cause problems in a core software product. Growing too quickly can cause a product to have a bloated user interface. If the backend infrastructure layer expands too quickly, sensitive data could be left exposed due to a lack of proper software security policies.

Chris Yeh joins the show to talk about the strategy of Blitzscaling and his wide-ranging career. Chris studied creative writing and product design at Stanford before joining DE Shaw, the famous quantitative hedge fund. Later, he became an investor and worked in several leadership roles in software companies.

His wide range of experiences make Chris an excellent author and conversationalist. We explored the ideas of both Blitzscaling and his previous book The Alliance, which lays out a modern vision for the dynamic between employers and employees. We also talked about investing, Dungeons and Dragons, and podcasting.

", + "Episodes Title": "Blitzscaling with Chris Yeh", + "Episodes Uid": "SED4491497952", + "Episodes Audio File": "2bd157be9ad8c580ac06cca60e9c78fb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5vp", + "Episodes ID": "ed86f340-e328-11ea-91a2-33f3c5f37cc7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_26_AfreshMachineLearningforFood.mp3", + "Episodes Pubdate Date": "2019-06-26", + "Episodes Summary": "

A grocery store contains fruit, vegetables, meat, bread, and other items that can expire. In order to keep these items in stock, the store must be aware of how much food has been sold and what has gone bad. When a food item is low in stock, the store needs to order more of that food from a central distribution system.

Managing food inventory is not simple. Some kinds of meat might expire faster than others. Avocados do not become ripe at the same rate as apples. In order to keep the shelves stocked, there are manual workflows for checking the inventory and ordering new inventory.

Afresh is a company that builds software for grocery stores. 

Afresh works with grocery chains that have a central distribution center. These grocery stores already have some software. At the back of the store, inventory management systems maintain records of the items that the store has on the shelves. At the front of the store, checkout systems detect what has been sold and help to update inventory. When the inventory is running low, the store can order more inventory from the central distribution center, so that trucks can deliver more inventory.

Afresh improves the operational intelligence of these stores by detecting spoilage among items that are prone to expiration, such as fruit. Volodomyr Kuleshov is the CTO and co-founder of Afresh and he joins the show to discuss the technical challenges of a grocery store, and the software that Afresh is building to make groceries more intelligent.

", + "Episodes Title": "Afresh: Grocery Store Software with Volodymyr Kuleshov", + "Episodes Uid": "SED3029154392", + "Episodes Audio File": "a4fbd023afbffefd390d4e284dc42757.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5h6", + "Episodes ID": "eee31138-e328-11ea-91a2-772048a7c900", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_19_Hasura.mp3", + "Episodes Pubdate Date": "2019-03-19", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Modern web development tools have given frontend developers more power.

On the frontend, JavaScript frameworks like React and Vue have become easier to work with. For deployment, tools like Netlify and Zeit give developers a workflow that is tightly integrated with GitHub. At the database layer, autoscaling document storage systems like Firebase and hosted Mongo solutions make it easier to work with objects.

There are also a multitude of APIs that give developers rich business functionality out of the box, making it easy to build applications around SMS, payments, and computer vision. If you are building a new application today, you have the option to build it around a completely “serverless” architecture.

As the backend and frontend have changed, the middleware to communicate between those layers has also evolved. GraphQL is a modern way of fetching data from disparate data sources.

In previous episodes, we have talked about how GraphQL works, and some common patterns for using GraphQL in mature applications. In today’s episode, Tanmai Gopal joins the show to describe how to use GraphQL in newer applications. Tanmai is the CEO of Hasura, a company building tools around GraphQL. He discusses the advantages of using serverless functions together with GraphQL, and how to architect an event-based serverless application.

", + "Episodes Title": "Serverless GraphQL with Tanmai Gopal", + "Episodes Uid": "SED7399593463", + "Episodes Audio File": "3e87cb8d5a7abf96240e735738a8b255.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2t5", + "Episodes ID": "f8f29a90-e328-11ea-91a2-0b884651680f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/softwarearchitecture_edited.mp3", + "Episodes Pubdate Date": "2017-06-20", + "Episodes Summary": "

Software architecture address the challenge of communicating and navigating large, complex systems to stakeholders, both technical and non-technical.  Over the years software architecture has gone in and out of fashion.  Today we discuss why software architecture is important, what it means to have software architecture, and how to properly structure teams and incorporate architecture.

Today’s show is guest hosted by David Curry. David sits down with Simon Brown to discuss the importance of having a common language for software systems.  Simon is an independent consultant specializing in software architecture, he is the author of Software Architecture for Developers, and founder of Structurizr.

If you are interested in hosting a show, check out softwareengineeringdaily.com/host

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Software Architecture with Simon Brown", + "Episodes Uid": "SED4313105644", + "Episodes Audio File": "5278a07611b005e817ad1b85fa007091.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3d6", + "Episodes ID": "f4ddc024-e328-11ea-91a2-5fb8a23ab3d1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/BrendanBurns.mp3", + "Episodes Pubdate Date": "2018-01-12", + "Episodes Summary": "

Kubernetes has become the standard system for deploying and managing clusters of containers. But the vision of the project goes beyond managing containers. The long-term goal is to democratize the ability to build distributed systems.

Brendan Burns is a co-founder of the Kubernetes project. He recently announced an open source project called Metaparticle, a standard library for cloud-native development:

Metaparticle builds on top of Kubernetes primitives to make distributed synchronization easier… It supplies language independent modules for locking and leader election as easy-to-use abstractions in familiar programming languages.

After decades of distributed systems research and application, patterns have emerged about how we build these systems. We need a way to lock a variable, so that two nodes will not be able to write to that variable in a nondeterministic fashion. We need a way to do master election, so that if the master node dies, the other nodes can pick a new node to orchestrate the system.

We know that just about every distributed application needs locking and leader election–so how can we build these features directly into our programming tools, rather than bolting them on?

With Kubernetes providing a standard operating system for distributed applications, we can start to build standard libraries that assume we have access to underlying Kubernetes primitives. Instead of calling out to external tools like Zookeeper and etcd, a standard library like Metaparticle will abstract them away.

An example: if I am writing a system to do distributed mapreduce, I would like to avoid thinking about node failures and race conditions. Brendan’s idea is to push those problems down into a standard library–so the next developer who comes along with a new idea for a multi-node application has an easier time.

Brendan Burns currently works as a distinguished engineer at Microsoft, and he joins the show to discuss why it is still hard to build distributed systems and what can be done to make it easier. This is the second time we have had Brendan on the show. The first time he came on, he discussed the history of Kubernetes, and some of the design decisions of the system. This episode was more about the future. Full disclosure: Microsoft (where Brendan is employed) is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kubernetes Vision with Brendan Burns", + "Episodes Uid": "SED7873362563", + "Episodes Audio File": "5c1a849959c583dd5aeab8b511eaba9e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 588, + "Episodes ID": "efcfa8cc-e328-11ea-91a2-dba1bdc1fcfc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_14_DanKohn.mp3", + "Episodes Pubdate Date": "2019-01-14", + "Episodes Summary": "

Chinese Internet companies operate at a massive scale.

WeChat has over a billion users and is widely used as the primary means of payment by urban Chinese consumers. Alibaba ships 12 million packages per day, which is four times the amount of Amazon. JD.com, a Chinese ecommerce company, has perhaps the largest production Kubernetes installation in the world.

China’s rapid adoption of Internet services, combined with a large population and a growing middle class has led to the creation of Internet giants on par with the social networks, ecommerce sites, and ridesharing startups of the United States.

Last November, I attended the first KubeCon China and saw firsthand how the Chinese Internet companies are using open source software to scale their infrastructure.

Despite the differences between the US and China, the culture of technologists at KubeCon felt familiar. In some ways, it was just like any other Kubernetes conference that I have attended: large numbers of engineers trying to find the cutting edge of technology, and learning how to solve the problems they are facing back at the office.

There were presentations on scaling databases and service meshes and machine learning on Kubernetes. Outside of these presentation halls, there were tables where you could pick up a translation device so that Chinese-only and English-only presentations could be understood by the other nationality.

Dan Kohn joins the show to talk about Chinese Internet companies and how they are adopting Kubernetes. Dan is the executive director of the Cloud Native Computing Foundation, an organization within the Linux Foundation that organizes KubeCon. Before joining the CNCF, Dan worked as an entrepreneur, engineer, and executive at several technology companies.

", + "Episodes Title": "Kubernetes in China with Dan Kohn", + "Episodes Uid": "SED3830656318", + "Episodes Audio File": "480be73afb22920b5fc4dc481268362e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4fx", + "Episodes ID": "f1692938-e328-11ea-91a2-ef3272503bb4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_11_RealEstateML.mp3", + "Episodes Pubdate Date": "2018-09-11", + "Episodes Summary": "

Stock traders have access to high volumes of information to help them make decisions on whether to buy an asset. A trader who is considering buying a share of Google stock can find charts, reports, and statistical tools to help with their decision. There are a variety of machine learning products to help a technical investor create models of how a stock price might change in the future.

Real estate investors do not have access to the same data and tooling. Most people who invest in apartment buildings are using a combination of experience, news, and basic reports.

Real estate data is very different from stock data. Real estate assets are not fungible–each one is arguably unique from all others, whereas one share of Google stock is the same as another share. But there are commonalities between real estate assets.

Just like collaborative filtering can be applied to find a new movie that is similar to the ones you have watched on Netflix, comparable analysis can be used to find an apartment building that is very similar to another apartment building which recently appreciated in asset value.

Skyline.ai is a company that is building tools and machine learning models for real estate investors. Or Hiltch is the CTO at Skyline.ai and he joins the show to explain how to apply machine learning to real estate investing. He also describes the mostly serverless architecture of the company. This is one of the first companies we have talked to that is so heavily on managed services and functions-as-a-service.

", + "Episodes Title": "Real Estate Machine Learning with Or Hiltch", + "Episodes Uid": "SED3844085715", + "Episodes Audio File": "98ed16af43d63f9663cf886eb411acf8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3wj", + "Episodes ID": "f2dcbe38-e328-11ea-91a2-b38fd312fa32", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_30_ContainerTools.mp3", + "Episodes Pubdate Date": "2018-05-30", + "Episodes Summary": "

Containers have improved deployments and resource utilization. Kubernetes created a platform to manage those containers and orchestrate them into distributed applications. In today’s episode, we explore tools that improve the workflow of the application developer who is working with Kubernetes, including Helm, Draft, and Brigade.

Helm is a package manager for Kubernetes, which allows users to find, share, and use software that is built for Kubernetes. The unit of installation for Helm users is a Helm Chart. Installing a Helm Chart can simplify the deployment of a database, load balancer, or continuous integration tool. Draft is a tool for simplifying the containerization process. When a developer runs Draft, a Dockerfile is created to containerize the application, and a Helm Chart is created to enable the application to be easily deployed.

Brigade is a tool for creating and running Kubernetes workflows. Brigade allows for event-driven scripting on top of Kubernetes. Chatops, continuous integration systems, and complex big data pipelines can all be defined with Brigade. Brigade is exciting, because it is a higher level tool on top of Kubernetes–in some ways similar to the “serverless on Kubernetes” systems we have covered in the past.

Ralph Squillace is a principal program manager with Microsoft, where he works on containers, Linux, and cloud products. Ralph joins the show to talk about how developing with containers has changed in the last few years, and how it will continue to evolve in the near future.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Container Native Development with Ralph Squillace", + "Episodes Uid": "SED8963500157", + "Episodes Audio File": "621594110955ae9d12f91e7d0bfe2be5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2u6", + "Episodes ID": "f7cbb02a-e328-11ea-91a2-6b5a71ce0a47", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CultureFit.mp3", + "Episodes Pubdate Date": "2017-07-03", + "Episodes Summary": "

“Culture fit” is a term that is used to describe engineers that have the right personality for a given company. In the hiring process, “lack of culture fit” is used to turn away engineers who are good enough at coding but just don’t seem right for the company. As today’s guest Ammon Bartram says, “lack of culture fit” usually means “lack of enthusiasm for what a company does.”

Ammon is the co-founder of Triplebyte, a company that is debugging the interviewing process. Triplebyte has interviewed thousands of engineers, and is discovering which aspects of the current hiring process make sense and which are based on superstition, or tradition. We had a great conversation about what culture really means, and how to hire effectively.

Check out our new topic feeds, in iTunes or wherever you find your podcasts. We’ve sorted all 500 of our old episodes into categories like business, blockchain, cloud engineering, JavaScript, machine learning, and greatest hits. Whatever specific area of software you are curious about, we have a feed for you. Check the show notes for more details.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Culture Fit with Ammon Bartram", + "Episodes Uid": "SED8806572526", + "Episodes Audio File": "ddfeff615cbcebb2276139596482e563.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3gd", + "Episodes ID": "f482fe28-e328-11ea-91a2-db4b453661c4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_01_MicroservicesZhamakDehgani.mp3", + "Episodes Pubdate Date": "2018-02-01", + "Episodes Summary": "

On this show, we spend a lot of time talking about CI/CD, data engineering, and microservices. These technologies have only been widely talked about for the last 5-10 years. That means that they are easy to adopt for startups that get founded in the last 5-10 years, but not necessarily for older enterprises.

Within a large enterprise, it can be challenging to make significant changes to how technology is used. Many of the listeners might even take it for granted that your source code is in git–but if you work at an enterprise that started building software in 1981, you might be moving source code around on FTP servers or floppy disks.

The difficulty of changing the technology within an enterprise gets compounded by culture. Culture develops around specific technologies. That is one interpretation of “Conway’s Law”–that the way an organization uses software informs an organization’s communication structure. This is no surprise–if your organization manages code using FTP servers and floppy disks, it will slow down your innovation.

Zhamak Dehghani is an engineer at ThoughtWorks, where she consults with enterprises to modernize their software and culture. She works off of a blueprint that describes specific steps that an enterprise can take towards modernizing: continuous integration; building a data pipeline; building a system of experimentation. In some ways, this conversation fits nicely with our shows about DevOps a few years ago. Full disclosure: ThoughtWorks is a sponsor of Software Engineering Daily.

To find all of our shows about DevOps, as well as links to learn more about the topics described in the show, download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "How to Change an Enterprise’s Software and Culture with Zhamak Dehghani", + "Episodes Uid": "SED6969681759", + "Episodes Audio File": "042894d9e9d5e53720da352c46f685f1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2it", + "Episodes ID": "04a059e0-e329-11ea-91a2-7b7a9ea9fd16", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/trump_edited.mp3", + "Episodes Pubdate Date": "2017-03-14", + "Episodes Summary": "

Donald Trump has either alarmed or excited everyone in the engineering community.

Some of the debates are based around innovation. Opponents to Trump say that his anti-immigration policies will reduce the innovation that relies on H1-B visas. Supporters of Trump say that his anti-regulation policies will unlock innovation that is restricted by bureaucracy.

Other debates are around philosophy and free speech. Opponents to Trump say that his views on women are retrograde and that he promotes racism and white nationalism. Supporters of Trump say that he is brave enough to say what people are really thinking, and that he is truly independent from the polarized, ossified political system.

Software Engineering Daily is a show about the world through the lens of the software engineer, and today our world is being shaped by Donald Trump. We needed to do an episode on this subject because so many of my day-to-day conversations with other engineers were becoming about Trump.

Brad Taylor is a senior engineer with Optimizely who has formed Tech Stands Up, a grassroots movement giving a voice to the rapidly growing concerns about the Trump administration’s policies affecting the tech community and its users. We had a stimulating conversation about the tradeoffs of a Trump administration from an engineer’s perspective.

Don’t worry–this is not becoming a show about politics.

Tech Stands Up: Pi Day Rally Tickets

TechStandsUp.org

", + "Episodes Title": "Trump with Brad Taylor", + "Episodes Uid": "SED1722735711", + "Episodes Audio File": "f39c6899744808a7b92d7e7bfec79a2e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2v6", + "Episodes ID": "f743d952-e328-11ea-91a2-3b817c070bc4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/mruby.mp3", + "Episodes Pubdate Date": "2017-07-17", + "Episodes Summary": "

Shopify is a company that helps customers build custom online storefronts. Shopify has built upon the same Ruby on Rails application since the founding of their business 12 years ago starting with Rails 0.5 and moving all the way to Rails 5.  

MRuby is a lightweight implementation of the Ruby language. Shopify made the decision to use mruby to allow customers to create custom scripts that are run every time a customer adds items to their cart. However, since mruby was a language implementation that was not widely used, Shopify opted to post a Bug Bounty to the HackerOne bug bounty platform to find security vulnerabilities in their use of mruby. What followed was a payout of over $500,000 as report after report flooded in of security vulnerabilities inside mruby itself. There was so many reports that Shopify made the decision to sandbox the mruby execution into separate processes and decreased the bounty awards by 90%.

In this episode, Jeremy Jung interviews Daniel Bovensiepen (BOH-ven-see-pen) about mruby and the Shopify bug bounty.

Mruby: http://mruby.org/

The $500,000 release: http://mruby.sh/201703270126.html

HackerOne bounty page: https://hackerone.com/shopify-scripts

American Fuzzy Lop: http://lcamtuf.coredump.cx/afl/

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "MRuby and Language Security with Daniel Bovensiepen", + "Episodes Uid": "SED9809925025", + "Episodes Audio File": "b0aecacc9072d2dbedfa61f5c976eaf7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3d7", + "Episodes ID": "f4c7f352-e328-11ea-91a2-8f0e801233d2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_15_FluentD.mp3", + "Episodes Pubdate Date": "2018-01-15", + "Episodes Summary": "

A backend application can have hundreds of services written in different programming frameworks and languages.

Across these different languages, log messages are produced in different formats. Some logging is produced in XML, some is produced in JSON, some is in other formats. These logs need to be unified into a common format, and centralized for any developer who wants to debug.

The popularity of Kubernetes is making it easier for companies to build this kind of distributed application, where different services of different languages are communicating over a network, with a variety of log message types.

Fluentd is a tool for solving this problem of log collection and unification. In today’s episode, Eduardo Silva joins the show to describe how Fluentd is deployed to Kubernetes, and what the role of Fluentd is within a Kubernetes logging pipeline.

We also discuss the company where Eduardo works–Treasure Data. The story of Treasure Data is unusual. The team started out doing log management, but has found itself moving up the stack, into marketing analytics, sales analytics, and customer data management. This story might be useful for anyone who is open source developer thinking about how to evolve your project into a business.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "FluentD with Eduardo Silva", + "Episodes Uid": "SED2595214297", + "Episodes Audio File": "9278c34b112bea36bbf97d9e09e78219.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ja", + "Episodes ID": "0431f8b0-e329-11ea-91a2-13e45537550f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/stripeantifraud_edited.mp3", + "Episodes Pubdate Date": "2017-03-17", + "Episodes Summary": "

Every company that deals with payments deals with fraud. The question is not whether fraud will occur on your system, but rather how much of it you can detect and prevent. If a payments company flags too many transactions as fraudulent, then real transactions might accidentally get flagged as well. But if you don’t reject enough of the fraudulent transactions, you might not be able to make any money at all.

Because fraud detection is such a difficult optimization problem, it is a good fit for machine learning. Today’s guest Michael Manapat works on machine learning fraud detection at Stripe.

This conversation explores aspects of both data science and data engineering. Michael seems to benefit from having a depth of knowledge in both aspects of the data pipeline, which made me question whether data science and data engineering are roles that an engineering organization wants to separate.

This is the third in a series of episodes about Stripe engineering. Throughout these episodes, we’ve tried to give a picture for how Stripe’s engineering culture works. We hope to do more experimental series like this in the future. Please give us feedback for what you think of the format by sending us email, joining the Slack group, or filling out our listener survey. All of these things are available on softwareengineeringdaily.com.

", + "Episodes Title": "Stripe Machine Learning with Michael Manapat", + "Episodes Uid": "SED4328455666", + "Episodes Audio File": "fa36cd4f85293cd7a8ede299f562e982.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4ah", + "Episodes ID": "f1c19a64-e328-11ea-91a2-93d03ee2117f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_13_Gitops.mp3", + "Episodes Pubdate Date": "2018-08-13", + "Episodes Summary": "

Continuous delivery is a way of releasing software without requiring software engineers to synchronize during a release.  Over the last decade, continuous delivery workflows have evolved as the tools have changed. Jenkins was one of the first continuous delivery tools and is still in heavy use today. Netflix’s open sourced Spinnaker has also been widely adopted.

As Kubernetes has grown in popularity, some engineers have developed a workflow around Kubernetes and Git known as GitOps. GitOps treats Git as the source of truth for deployments. Under GitOps, when a divergence occurs between your git repository’s configuration files and the state of your production infrastructure, your infrastructure should automatically adjust its state to align with the state defined in git.

Alexis Richardson is the CEO of Weaveworks, a company that has built tooling around GitOps. He joins the show to describe how GitOps works, and explain how it compares to other methods for continuous delivery.

", + "Episodes Title": "GitOps: Kubernetes Continuous Delivery with Alexis Richardson", + "Episodes Uid": "SED4361060924", + "Episodes Audio File": "c0e0fa572c1e071c1f6502189f4b2d68.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "34a", + "Episodes ID": "f6201bee-e328-11ea-91a2-f39b0569fda9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/BlocksizeDebate.mp3", + "Episodes Pubdate Date": "2017-10-10", + "Episodes Summary": "

Visa processes 1,600 transactions per second. PayPal processes 193 transactions per second. Bitcoin processes only 3-4 transactions per second. In order to fulfill the dreams of financial programming–in order to get decentralized, peer-to-peer micropayments–Bitcoin needs a much higher transaction throughput. Bitcoin’s scalability issues have led to debates within the community and changes in the software.

In this episode, Jordan Clifford gives an overview of some of the scaling limitations of Bitcoin, and discusses SegWit, a change to the Bitcoin protocol that improves scalability. Jordan was previously on the show to discuss the basics of Ethereum and Bitcoin. This episode covers some advanced topics of Bitcoin, and if you are out of your comfort zone, don’t worry–you aren’t alone.

Stay tuned at the end of the episode for Jeff Meyerson’s tip about assessing cultural fit at a company: brought to you by Indeed Prime.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! We are building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend–and more projects are coming soon. If you have ideas for how software engineering media content should be consumed, or if you are interested in contributing code, check out github.com/softwareengineeringdaily, or join our Slack channel (there’s a link on our website)–or send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Bitcoin Segwit with Jordan Clifford", + "Episodes Uid": "SED5255973902", + "Episodes Audio File": "d2d226733675a898be849b9898add008.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5pv", + "Episodes ID": "ee1246a2-e328-11ea-91a2-cf276bf5c165", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_15_FBJocelyn.mp3", + "Episodes Pubdate Date": "2019-05-15", + "Episodes Summary": "

Facebook engineering is designed to self-assemble.

When an engineer joins Facebook, the engineer goes through boot camp, where they are exposed to multiple projects to find a good fit in terms of technical skills and personal preferences. Since there are so many different initiatives within the company at any given moment, a new hire can usually find something to work on through this exploration.

As an engineer builds credibility within Facebook, opportunities to move to other projects or to become a manager will present themselves, allowing the engineer to move within the company as they mature and their interests change. The sense of autonomy and freedom to explore is one feature of Facebook engineering that distinguishes the company.

Facebook is a flat, decentralized organization by nature. But there have been existential moments in Facebook’s history where an executive mandate was required. During these existential situations, Facebook centralizes and becomes a more top-down environment.

Facebook’s most crucial inflection point to date was its shift to focusing on mobile computing.

Even two years after the launch of the iPhone, it was not obvious that the world of consumer computing would change completely due to mobile devices. Facebook was becoming a dominant place where consumers navigated to on desktop, and Facebook engineering was focused on optimizing that desktop experience.

As the impact of the iPhone became noticeable, Facebook found itself with a desktop web product in the middle of a platform shift away from the desktop. During this same time, Facebook was beginning to succeed with its advertising platform and was evaluating an initial public offering.

Facebook leadership was able to recognize the importance of mobile computing in time to develop high quality mobile applications, but there were numerous challenges.

The Facebook desktop web app had been difficult enough to build due to the unprecedented data requirements and amount of interactivity. Mobile introduced the additional hurdles of limited bandwidth and distinct native operating systems in Android and iPhone.

Facebook’s early efforts to build a mobile application involved a cross-platform HTML5 solution. HTML5 had insufficient performance for Facebook’s needs, and the company needed to develop native apps in order to deliver the desired experience.

Facebook’s ability to pivot to mobile is comparable to the classic story of Intel pivoting from a memory company to a microprocessor company. To succeed at mobile application development, Facebook had to shift its focus dramatically, reallocating engineering resources and acqui-hiring small mobile companies in order to build up the domain expertise for mobile.

As a side effect of this transition to mobile, Facebook developed an understanding of how dramatically software engineering was changed by the introduction of smartphones and the high bandwidth requirements of social networking. The challenges of this new paradigm led to the development of open source tools such as GraphQL and React Native, which have allowed countless projects to build applications more easily.

Jocelyn Goldfein was an engineering director at Facebook for four years, from 2010 to 2014. She currently works as an investor at Zetta Venture Partners. In her time at Facebook, Jocelyn saw the shift to mobile firsthand. In today’s episode, she describes how Facebook management works, and gives her perspective on the distinguishing characteristics of the engineering organization as a whole.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Facebook Management with Jocelyn Goldfein", + "Episodes Uid": "SED4872503091", + "Episodes Audio File": "c7192d6d0def6f3cd8a3cf7013a9c734.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4n5", + "Episodes ID": "f1225c06-e328-11ea-91a2-73a718333191", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_03_Cursor.mp3", + "Episodes Pubdate Date": "2018-10-03", + "Episodes Summary": "

Linkedin is an organization with thousands of employees. An enterprise of that size starts to develop problems with data collaboration. Data collaboration is the process of sharing and analyzing data with multiple users, such as data scientists, business analysts, and engineers.

How do data scientists know what questions to ask? How do business analysts know the right way to query a database? How does a data engineer even find where the right database is within the company infrastructure? And how can these different users share information with each other so that redundant work is avoided?

When Adam Weinstein was at Linkedin, he saw these problems firsthand. The process of accessing and utilizing data felt slow and broken. Engineers were searching through a company wiki to find out how to leverage data, and the wiki was often out of date. When an engineer would leave the company, there was not a durable, institutional memory of how that engineer worked with data.

Adam used this experience as inspiration for Cursor, a tool for data collaboration. Cursor allows different users in the data pipeline to share data sets, queries, access patterns, and comments about data within a company. Cursor is used by Linkedin, Slack, Apple, and other companies. Adam is the CEO of Cursor, and he joins the show for an interview about the problems and opportunities of data collaboration.

", + "Episodes Title": "Cursor: Data Collaboration with Adam Weinstein", + "Episodes Uid": "SED2002210051", + "Episodes Audio File": "9a1af1fa7b18ac514b6b715cbd84e95d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4hs", + "Episodes ID": "f1574470-e328-11ea-91a2-9fc4adae4b42", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_17_PracticalDev.mp3", + "Episodes Pubdate Date": "2018-09-17", + "Episodes Summary": "

The DEV Community is a platform where developers share ideas, programming advice, and tools. Ben Halpern started it after running an extremely successful Twitter account creating humorous tweets for developers. One way to describe DEV Community is as a cross between Medium, Stack Overflow, and Reddit–but it has its own personality, so I recommend checking it out.

The DEV Community was open sourced, and we discussed the challenges and the opportunities of having an open source social network. We also talked about his plans for the future, and where he is taking DEV Community.

Ben is an entrepreneur who tries lots of different creative projects, so his perspective has always resonated with me. Ben has been on the show a few times before, when we talked about the state of developer media, side projects, and the identity of the software engineer.

DEV Community was originally called Practical Dev, which I mistakenly referred to it as in the earlier parts of the show.

", + "Episodes Title": "DEV Community with Ben Halpern", + "Episodes Uid": "SED5158764008", + "Episodes Audio File": "aa507eff6f96ace965fe148f281190f2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2b0", + "Episodes ID": "0fe2a434-e329-11ea-91a2-e3b5bbb52c83", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/biocomputation_edited.mp3", + "Episodes Pubdate Date": "2016-11-28", + "Episodes Summary": "

Biology research at Microsoft is focused on three main areas: molecular programming, synthetic biology, and stem cell biology. At the intersection of biology and computing there are implications for health, medicine, and efficient computing techniques. The field of Biological Computation is in its early days, and there is still lots of work to be done.

Colin Gravill works in the computational science group at Microsoft Research, and today he explains how Microsoft is investigating biology with the same curiosity and pragmatism that Microsoft investigates computer science.

I’d love to do more shows at the border between software and biology–if you have suggestions, please send me an email. jeff@softwareengineeringdaily.com

", + "Episodes Title": "Biological Computation with Colin Gravill", + "Episodes Uid": "SED4859584736", + "Episodes Audio File": "fac515638610371a54434db3961db9f6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "47i", + "Episodes ID": "f21e1ed8-e328-11ea-91a2-a77b3a800c01", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_24_VideoML.mp3", + "Episodes Pubdate Date": "2018-07-24", + "Episodes Summary": "

Video streaming platforms like Netflix offer a convenient way to watch video content. We are now able to watch our favorite TV shows, movies, or content creators on a range of devices. However, buffering while watching videos can be a painful experience on mobile phones and tablets that use 4G or LTE. As streaming becomes available to a wider range of devices with varying bandwidth restrictions, different encodings of the video need to be created for different devices, and different bandwidth situations.

To get the best quality viewing possible with the bandwidth available to connections, there needs to be a balance between the resolution of the video, and the bitrate, which defines the data that the video consumes.

Mux is a company that builds video hosting and analytics. Ben Dodson is a data scientist at Mux, who built a system for optimizing the bitrate of videos through machine learning. In this episode we discuss video encoding and how Mux solved the problem of serving the highest quality video with the ideal bitrate.

", + "Episodes Title": "Video Machine Learning with Ben Dodson", + "Episodes Uid": "SED5722983131", + "Episodes Audio File": "4142fe31ccdab4b95ccd7094a0770555.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5l5", + "Episodes ID": "ee98f0bc-e328-11ea-91a2-43644b6888a2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_10_RelationalLearning.mp3", + "Episodes Pubdate Date": "2019-04-10", + "Episodes Summary": "

RECENT UPDATES:

FindCollabs $5000 Hackathon Ends Saturday April 15th, 2019

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

Data sets can be modeled in a row-wise, relational format. When two data sets share a common field, those data sets can be combined in a procedure called a join. A join combines the data of two data sets into one data set that is often bigger than the initial two data sets independently occupied. In fact, this new data set is often so much bigger that it creates problems for the machine learning engineers.

Arun Kumar is an assistant professor at UC San Diego. He joins the show to discuss the modern lifecycle of machine learning models, and the gaps in the tooling.

Arun’s research into improving processing of joined data sets has been adopted by companies such as Google. Some of that research has been adapted into open source machine learning tools that improve the performance of machine learning jobs with minimal code required.

", + "Episodes Title": "Machine Learning Joins with Arun Kumar", + "Episodes Uid": "SED1492339868", + "Episodes Audio File": "6af8840ce0a04757549e40179d396d47.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1y9", + "Episodes ID": "1d8db9b6-e329-11ea-91a2-eb4e70e803ee", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DIYPS_Edited.mp3", + "Episodes Pubdate Date": "2016-05-04", + "Episodes Summary": "

Patients with Type-1 diabetes need to frequently pump insulin into their bodies. In order to know when to pump insulin, these patients have a continuous glucose monitor alarm which detects incorrect levels of blood glucose.

When the alarm goes off, the diabetes patient administers insulin manually through the pump. In an ideal world, the alarm would communicate with the insulin pump, creating a closed loop. But the world of outdated medical devices is not ideal.

Dana Lewis is a developer of an open-source, closed-loop artificial pancreas called the Do-It-Yourself Pancreas system. Dana joins the show to discuss how she hacked together her artificial pancreas using a Raspberry pi plugged into these medical devices.  This is a fascinating story of reverse engineering, internet of things, and the hacker mentality.

Sponsors

", + "Episodes Title": "Open Source Pancreas with Dana Lewis", + "Episodes Uid": "SED2376058316", + "Episodes Audio File": "5bcab99094e442c8a15752dfb70c59ba.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 622, + "Episodes ID": "ecc6f0e0-e328-11ea-91a2-d37a1eceac67", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_14_IstioMeshwithVarunTalwar.mp3", + "Episodes Pubdate Date": "2019-08-14", + "Episodes Summary": "

The service mesh abstraction allows for a consistent model for managing and monitoring the different components of a microservices architecture. 

In the service mesh pattern, each service is deployed with a sidecar container that contains a service proxy. These sidecars are collectively referred to as the “data plane.” Each sidecar provides the service that it is deployed next to with a set of features such as security policy, rate limiting, and monitoring instrumentation.

The sidecars in the data plane communicate with a central module called a control plane. In the control plane, an engineer can operate across these individual services at scale, by pushing out updates to them.

Kubernetes has made it easier to manage large fleets of microservices, and has led to wider adoption of service mesh. Istio is one of the most popular service mesh products. In today’s show, Varun Talwar returns to the show to describe the state of the Istio project and the process of deploying Istio to a cluster. Varun is the CEO of Tetrate, a company building an enterprise-ready service mesh. Prior to Tetrate, Varun was at Google, where he helped found the gRPC and Istio projects.

", + "Episodes Title": "Service Mesh Deployment with Varun Talwar", + "Episodes Uid": "SED5465475864", + "Episodes Audio File": "ec288594eec409ac1728ea4dab92b7b5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5bp", + "Episodes ID": "ef6a0fe4-e328-11ea-91a2-87f2880b2b8d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_12_M3.mp3", + "Episodes Pubdate Date": "2019-02-12", + "Episodes Summary": "

Uber manages the car rides for millions of people. The Uber system must remain operational 24/7, and the app involves financial transactions and the safety of passengers.

Uber infrastructure runs across thousands of server instances and produce terabytes of monitoring data. The monitoring data is used to understand the health of the software systems as well as relevant business metrics, such as driver efficiency, daily revenues, and user satisfaction.

Uber adopted the Prometheus monitoring system to manage their monitoring data. Prometheus regularly scrapes metrics across infrastructure to gather time series data about the state of everything across Uber. As the usage of Prometheus has grown within the company, Uber has had to figure out how to scale their monitoring platform.

M3 is a monitoring system built at Uber to scale Prometheus and provide a platform that can effectively scale the data storage as well as the query serving. Rob Skillington is a staff software engineer at Uber, and he joins the show to talk about monitoring at Uber–from the requirements of the system to the implementation of M3.

At Uber, M3 powers dashboards, ad-hoc queries, and alerting. M3 was open sourced to give other users access to a scalable Prometheus solution. In a previous episode with Brian Boreham, we discussed one strategy for scaling Prometheus. Today’s episode covers another scalability solution, with M3.

", + "Episodes Title": "Uber’s Monitoring Platform with Rob Skillington", + "Episodes Uid": "SED5637909326", + "Episodes Audio File": "dd4bd747b9d06e061206cc8df123f954.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ve", + "Episodes ID": "2e521a6c-e329-11ea-91a2-d379c00d787c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Free_Code_Camp.mp3", + "Episodes Pubdate Date": "2015-10-28", + "Episodes Summary": "

Free Code Camp is an open source community dedicated to teaching people how to code while also helping non-profits

Quincy Larson is the Founder of Free Code Camp, and previously was the director of several schools in the U.S. and China.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Free Code Camp with Quincy Larson", + "Episodes Uid": "SED9427237231", + "Episodes Audio File": "a0e5af622e6f8d6a537fa9eac77c45b9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3lk", + "Episodes ID": "f3dec2ae-e328-11ea-91a2-eb8976129147", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_20_AnthonyJaxx.mp3", + "Episodes Pubdate Date": "2018-03-20", + "Episodes Summary": "

Anthony Diiorio was involved with Ethereum since the earliest days. He was one of the first people to see the Ethereum ideas presented by Vitalik Buterin, and he invested deeply in Ethereum–both financially and by helping to establish the early Ethereum community. Anthony started Decentral in 2014, which is a hub for his projects in the cryptocurrency space, the most impactful project being Jaxx.

Jaxx is a blockchain wallet that can hold multiple different cryptocurrencies. It works by connecting a small client-side application to remote full nodes. The user interface is simple, and Jaxx maintains the full node instances that the small client-side application connects to. We discuss the architecture of Jaxx in more detail during this episode.

We also talk about Anthony’s background–which includes a wide range of businesses: marketing, patio door manufacturing, real estate, and eventually blockchains. Anthony had a wealth of information to provide around entrepreneurship–both inside and outside of the blockchain space.

If you are looking for all 700 episodes of Software Engineering Daily, check out our apps on the iOS or Android app store. We’ve got tons of episodes on blockchains, business, distributed systems, and tons of other topics. If you want to become a paid subscriber to Software Engineering Daily, you can hear all of our episodes without ads–you can subscribe at softwaredaily.com. And all of the code for our apps is open source. If you are looking for an open source community to be a part of, come check out github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "The Business of Decentralization with Anthony Diiorio", + "Episodes Uid": "SED9950209794", + "Episodes Audio File": "de4ac2c7c57597fa2254eb7326b578cc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5go", + "Episodes ID": "eeffd4c6-e328-11ea-91a2-db7b5e27cd11", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_14_LinuxwithShuahKhan.mp3", + "Episodes Pubdate Date": "2019-03-14", + "Episodes Summary": "

An operating system kernel manages the system resources that are needed to run applications. The Linux kernel runs most of the smart devices that we interact with, and is the largest open source project in history.

Shuah Khan has worked on operating systems for two decades, including 13 years at HP and 5 years at Samsung. She has worked on proprietary operating systems and a variety of Linux operating system environments, including mobile devices. Shuah joins the show to discuss her work within Linux and her experience contributing to open source.

Shuah has made significant contributions to kselftest, a set of tests for Linux. Testing the Linux kernel is complicated. Because there is so much depth to the codebase, and such a variety of ways that Linux can be used, there is also a variety of ways that the operating system gets tested. There is smoke testing, performance testing, and regression testing. There are trees of tests, and as a developer you may only want to run a subset of the tests in that tree.

The conversation with Shuah ranged from the low level practices of testing the kernel to a high level discussion of how the Linux kernel can reveal dynamics of human nature.

", + "Episodes Title": "Linux Kernel Development with Shuah Khan", + "Episodes Uid": "SED1466265128", + "Episodes Audio File": "aaeec7fe81694aafa99af9f7bffcc7f2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4i0", + "Episodes ID": "f152c562-e328-11ea-91a2-e31ae559b07f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_18_AzurePipelines.mp3", + "Episodes Pubdate Date": "2018-09-18", + "Episodes Summary": "

Continuous integration and delivery allows teams to move faster by allowing developers to ship code independently of each other. A multi-stage CD pipeline might consist of development, staging, testing, and production. At each of these stages, a new piece of code undergoes additional tests, so that when the code finally makes it to production, the developers can be certain it won’t break the rest of the project.

In a company, the different engineers working on a software project are given the permissions to ship code through a continuous delivery pipeline. Employees at a company have a strong incentive not to push buggy code to production. But what about open source contributors? What does the ideal continuous delivery workflow look like for an open source project?

Abel Wang works on Azure Pipelines, a continuous integration and delivery tool from Microsoft. Azure Pipelines is designed to work with open source projects as well as companies. Abel joins the show to talk about using continuous integration and delivery within open source, and the process of designing a CI/CD tool that can work in any language and environment. Full disclosure: Microsoft is a sponsor of SE Daily.

", + "Episodes Title": "Continuous Delivery Pipelines with Abel Wang", + "Episodes Uid": "SED9452352468", + "Episodes Audio File": "5bf2d848d43e7dd362258f07ea60a721.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "46b", + "Episodes ID": "f23ef522-e328-11ea-91a2-1f1b19a57fdf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_13_MLDeployments.mp3", + "Episodes Pubdate Date": "2018-07-13", + "Episodes Summary": "

Machine learning models allow our applications to perform highly accurate inferences. A model can be used to classify a picture as a cat, or to predict what movie I might want to watch. But before a machine learning model can be used to make these inferences, the model must be trained and deployed.

In the training process, a machine learning model consumes a data set and learns from it. The training process can consume significant resources. After the training process is over, you have a trained model that you need to get into production. This is known as the “deployment” step.

Deployment can be a hard problem. You are taking a program from a training environment to a production environment. A lot can change between these two environments. In production, your model is running on a different machine–which can lead to compatibility issues. If your model serves a high volume of requests, it might need to scale up. In production, you also need caching, and monitoring, and logging.

Large companies like Netflix, Uber, and Facebook have built their own internal systems to control the pipeline of getting a model from training into production. Companies who are newer to machine learning can struggle with this deployment process, and these companies usually don’t have the resources to build their own machine learning platform like Netflix.

Diego Oppenheiner is the CEO of Algorithmia, a company that has built a system for automating machine learning deployments. This is the second cool product that Algorithmia has built, the first being the algorithm marketplace that we covered in an episode a few years ago.

In today’s show, Diego describes the challenges of deploying a machine learning model into production, and how that product was a natural complement to the algorithms marketplace. Full disclosure: Algorithmia is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Machine Learning Deployments with Diego Oppenheimer", + "Episodes Uid": "SED4551822188", + "Episodes Audio File": "0876077efb867d55dfdfb40238726797.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 599, + "Episodes ID": "efb401bc-e328-11ea-91a2-f72aff711829", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_22_Rsocket.mp3", + "Episodes Pubdate Date": "2019-01-22", + "Episodes Summary": "

Netflix has thousands of service instances communicating with each other. When a Netflix client on a smartphone makes a request for a movie, that request hits Netflix’s backend, where the request is fulfilled by a chain of requests through different services.

Services and clients communicate using several different interaction patterns. A service might send a single request and expect a single response. Or it might fire and forget, not expecting a response. A service also might send a single request and expect a stream of messages to be sent back over the network. In a highly interactive application like Netflix, there is a frequent use of “streams” of data.

RSocket is a protocol that makes reactive streams easier to work with. Ryland Degnan is the CTO of Netifi, and he joins the show to discuss reactive streams and service-to-service networking. Ryland worked at Netflix on the Edge Platform team for four years, and he shares his experience working at Netflix, the challenges of networking at scale, and the company he is building around RSocket.

", + "Episodes Title": "RSocket: Reactive Streaming Service Networking with Ryland Degnan", + "Episodes Uid": "SED9750390464", + "Episodes Audio File": "2c973c3f9e9ae07628f21b8588168182.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4s8", + "Episodes ID": "f0dd1a4c-e328-11ea-91a2-d7e17bbcb2ed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_23_DevSecOps_Edward_Thompson.mp3", + "Episodes Pubdate Date": "2018-10-23", + "Episodes Summary": "

DevSecOps emphasizes moving security out of a siloed audit process and distributing security practices throughout the software supply chain.

In the past, software development usually followed a waterfall development process. Each step in building software was serialized, one after another. First, software was planned. Then it was built. Then it was tested. Finally, the software received a security audit at the end. If a security vulnerability was not discovered during that audit, it was likely that the software would be released with the vulnerability.

With continuous delivery, we can be continuously checking for security. Every new release can be tested against a battery of automated security tests. The open source libraries we use can be scanned to make sure they are up-to-date with patched versions. Static analysis can discover memory leaks and buffer overrun vulnerabilities.

Edward Thomson is the principal program manager for Azure DevOps at Microsoft. He joins the show to talk about how an organization can adopt DevSecOps and introduce security practices into continuous delivery pipelines. We also talk more philosophically about security–defining the most common security risks of a software company today, from “shadow IT infrastructure” to phishing. Full disclosure: Microsoft is a sponsor of Software Engineering Daily.

We recently launched a new podcast: Fintech Daily! Fintech Daily is about payments, cryptocurrencies, trading, and the intersection between finance and technology. You can find it on fintechdaily.co or Apple and Google podcasts. We are looking for other hosts who want to participate. If you are interested in becoming a host, send us an email: host@fintechdaily.co

", + "Episodes Title": "DevSecOps with Edward Thomson", + "Episodes Uid": "SED9599441346", + "Episodes Audio File": "de15ab898830af125a84583577ff5e71.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "59p", + "Episodes ID": "efa6c952-e328-11ea-91a2-9b6fee4d5947", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_25_Kubeflow.mp3", + "Episodes Pubdate Date": "2019-01-25", + "Episodes Summary": "

When TensorFlow came out of Google, the machine learning community converged around it. TensorFlow is a framework for building machine learning models, but the lifecycle of a machine learning model has a scope that is bigger than just creating a model. Machine learning developers also need to have a testing and deployment process for continuous delivery of models.

The continuous delivery process for machine learning models is like the continuous delivery process for microservices, but can be more complicated. A developer testing a model on their local machine is working with a smaller data set than what they will have access to when it is deployed. A machine learning engineer needs to be conscious of versioning and auditability.

Kubeflow is a machine learning toolkit for Kubernetes based on Google’s internal machine learning pipelines. Google open sourced Kubernetes and TensorFlow, and the projects have users AWS and Microsoft. David Aronchick is the head of open source machine learning strategy at Microsoft, and he joins the show to talk about the problems that Kubeflow solves for developers, and the evolving strategies for cloud providers.

David was previously on the show when he worked at Google, and in this episode he provides some useful discussion about how open source software presents a great opportunity for the cloud providers to collaborate with each other in a positive sum relationship.

", + "Episodes Title": "Kubeflow: TensorFlow on Kubernetes with David Aronchick", + "Episodes Uid": "SED1649767466", + "Episodes Audio File": "319db41da7f04250a53d9684295e4561.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 389, + "Episodes ID": "f59307b8-e328-11ea-91a2-131a7e82381e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RainforestQA.mp3", + "Episodes Pubdate Date": "2017-11-17", + "Episodes Summary": "

Automation is changing the labor market.

To automate a task, someone needs to put in the work to describe the task correctly to a computer. For some tasks, the reward for automating a task is tremendous–for example, putting together mobile phones. In China, companies like FOXCONN are investing time and money into programming the instructions for how to assemble your phone. Robots execute those instructions.

FOXCONN spends millions of dollars deploying these robots, but it is a worthwhile expense. Once FOXCONN pays off the capital investment in those robots, they have a tireless workforce that can build phones all day long. Humans require training, rest, and psychological considerations. And with robots, the error rate is lower. Your smart phone runs your life, and you do not want the liability of human imperfection involved in constructing that phone.

As we race towards an automated future, the manual tasks that get automated first depend on their economic value. The manual labor costs of smartphone construction is a massive expense for corporations. This is also true for truck driving, food service, and package delivery. The savings that will be reaped from automating these tasks are tremendous–regardless of how we automate them.

There two ways of building automated systems: rule-based systems and machine learning.

With rule-based systems, we can describe to the computer exactly what we want it to do–like following a recipe. With machine learning, we can train the computer by giving it examples and let the computer derive its own understanding of how to automate a task.

Both approaches to automation have difficulties. A rule-based approach requires us to enumerate every single detail to the machine. This might work well in a highly controlled environment like a manufacturing facility. But rule-based systems don’t work well in the real world, where there are so many unexpected events, like snowstorms.

As we reported in a previous episode about how to build self-driving cars, engineers still don’t quite know what the right mix of rule-based systems and machine learning techniques are for autonomous vehicles. But we will continue to pour money into solving this problem, because the investment is worth figuring out how to train the machine.

The routine tasks in our world will be automated given enough time. How soon something will be automated depends on how expensive that task is when it is performed by a human, and how hard it is to design an artificial narrow intelligence to perform the task instead of a human.

Manual software testing is another type of work that is being automated today.

If I am building a mobile app to play podcast episodes, and I make a change to the user interface, I want to have manual quality assurance (QA) testers run through tests that I describe to them, to make sure my change did not break anything. QA tests describe high level application functionality. Can the user register and log in? Can the user press the play button and listen to a podcast episode on my app?

Unit tests are not good enough, because unit tests only verify the logic and the application state from the point of view of the computer itself. Manual QA tests ensure that the quality of the user experience was not impacted.

With so many different device types, operating systems, and browsers, I need my QA test to be executed in all of the different target QA environments. This requires lots of manual testers. If I want manual testing for every deployment I push, that manual testing can get expensive.

RainforestQA is a platform for QA testing that turns manual testing into automated testing. The manual test procedures are recorded, processed by computer vision, and turned into automated tests. RainforestQA hires human workers from Amazon Mechanical Turk to execute the well-defined manual tests, and the recorded manual procedure is used to train the machines that can execute the same task in the future.

Russell Smith is the CTO and co-founder of RainforestQA, and he joins the show to explain how RainforestQA works: the engineering infrastructure, the process of recruiting workers from mechanical turk, and the machine learning system for taking manual tasks and automating them.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Training the Machines with Russell Smith", + "Episodes Uid": "SED3329474393", + "Episodes Audio File": "6240e0d7f0682895edeed416d7502b21.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2iv", + "Episodes ID": "04f77bbc-e329-11ea-91a2-ef80c0ad7a47", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Using_CQRS.mp3", + "Episodes Pubdate Date": "2017-03-10", + "Episodes Summary": "

Command Query Responsibility Segregation (CQRS) is a powerful concept that has the potential to make for reliable and maintainable systems.  It is also broadly misunderstood and means different things to different people.

Derek Comartin learned about the idea after viewing some talks by Greg Young and has since successfully applied the approach with great success and it has transformed the way he views features, business requirements, and dependencies.  The result is a system that is easier to maintain and faster to enhance.  Among his key lessons are that slices are better than layers, mediators improve dependency management, and cohesion is better applied to business concerns than to technical ones.

In this episode, Derek joins Dave Rael for a conversation about CQRS and applying it to make your code your own and to separate it from technical concerns in order to make your software development operation work better and faster.

", + "Episodes Title": "Using CQRS to Make Controllers Lean with Derek Comartin", + "Episodes Uid": "SED5104050144", + "Episodes Audio File": "243928e84689ca96892ec3f9e00f79c2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2rq", + "Episodes ID": "fa534984-e328-11ea-91a2-d3890f0bb78c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/gitlab_edited.mp3", + "Episodes Pubdate Date": "2017-06-02", + "Episodes Summary": "

On January 31st 2017, GitLab experienced a major outage of their online repository hosting service. The primary database server experienced data loss due to a combination of malicious spam attacks and engineering mistakes that occurred while trying to respond to those spam attacks.

GitLab responded to the event transparently. The company put up a postmortem describing the event in detail. In subsequent posts, GitLab expressed sympathy for the employee who made engineering mistakes that led to the deletion of data. The employee was not judged or disciplined for an understandable error.

The response from the developer community was very positive. Engineers know that building cloud services is hard. Engineering is as much about avoiding errors as it is about appropriately responding to the inevitable mistakes.

GitLab is a developer platform that combines repository hosting with several other features–issue tracking, code review, and CD. Today’s guest is Pablo Carranza, who works on infrastructure at GitLab. In this episode, he walks us through GitLab’s product, the engineering stack, and a postmortem of the outage. We also discuss working at Amazon, and the importance of postmortems, which I first encountered at Amazon.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "GitLab with Pablo Carranza", + "Episodes Uid": "SED3702179026", + "Episodes Audio File": "efd568214368a318a46ab07798a04fc3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5w2", + "Episodes ID": "ed7483e0-e328-11ea-91a2-afedd172d5c5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_01_FoundationDB.mp3", + "Episodes Pubdate Date": "2019-07-01", + "Episodes Summary": "

FoundationDB is a multi-model distributed key-value store. It is fully ACID compliant and horizontally scalable. FoundationDB is not usually used directly by an application developer–FoundationDB is a foundational building block for higher level distributed systems such as the metadata store for data warehousing tool Snowflake.

Ryan Worl is a software engineer who specializes in FoundationDB. He joins the show to discuss the architecture of FoundationDB, including the roles of different server components and the read and write path of FoundationDB. We also talk about applications of FoundationDB, and how it compares to storage engines such as RocksDB and databases such as CockroachDB and Spanner.

", + "Episodes Title": "FoundationDB with Ryan Worl", + "Episodes Uid": "SED2521019584", + "Episodes Audio File": "4558e3538079644df5b17616775675af.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "56a", + "Episodes ID": "efe70ed6-e328-11ea-91a2-af51a35126e2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_07_StatefulKubernetes.mp3", + "Episodes Pubdate Date": "2019-01-07", + "Episodes Summary": "

In a cloud infrastructure environment, failures happen regularly. The servers can fail, the network can fail, and software bugs can crash your software unexpectedly.

The amount of failures that can occur in cloud infrastructure is one reason why storage is often separated from application logic. A developer can launch multiple instances of their application, with each instance providing a “stateless” environment for serving API requests.

When the application needs to save state, it can make a call out to a managed cloud infrastructure product. Managed cloud databases provide a reliable place to manage application state. Managed object storage systems like Amazon S3 provide a reliable place to store files.

The pattern of relying on remote cloud services does not work so well for on-prem and hybrid cloud environments. In these environments, companies are managing their own data centers and their own storage devices. As companies with on-prem infrastructure adopt Kubernetes, there is a need for ways to manage on-prem storage through Kubernetes.

Saad Ali is a senior engineer at Google, where he works on Kubernetes. He is also a part of the Kubernetes Storage Special Interest Group. Saad joins the show talk about how Kubernetes interacts with storage, and how to manage stateful workloads on Kubernetes. We discuss the basics of Kubernetes storage, including persistent volumes and the container storage interface.

", + "Episodes Title": "Stateful Kubernetes with Saad Ali", + "Episodes Uid": "SED4129681979", + "Episodes Audio File": "a23900d7fb75661377fc093daebd0d5b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2x1", + "Episodes ID": "f7274e9a-e328-11ea-91a2-532a6875c649", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SWinLatinAmerica.mp3", + "Episodes Pubdate Date": "2017-07-25", + "Episodes Summary": "

Access to education is something everyone strives for but not all achieve–especially education that leads to meaningful and well-paying work. In today’s world where software is eating all sorts of industries, access to a good technical education is still out of the reach of many people.

Laboratoria is a social enterprise which teaches women from low-income backgrounds in Peru, Mexico and Chile how to code and helps place them in coding jobs. It was started in Peru by couple Mariana Costa (CEO) and Herman Marin (CTO) along with a friend after they found it difficult to hire developers for a web agency they had started.

In today’s episode, Mariana talks to Carl Mungazi about how Laboratoria is using software engineering to change the lives of the women in Latin America whilst also meeting a demand for good technical talent. She discusses the challenges faced by her students, who sometimes spend hours traveling to the school, and her plans for training 10,000 developers over the next five years.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Software in Latin America with Mariana Costa", + "Episodes Uid": "SED7827836079", + "Episodes Audio File": "ed86b36bfb188c5d9639cc3d46da3bc5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ow", + "Episodes ID": "ee30e42c-e328-11ea-91a2-6ba07ddfe4b9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_07_KubernetesandVirtualization.mp3", + "Episodes Pubdate Date": "2019-05-07", + "Episodes Summary": "

Modern server infrastructure usually runs in a virtualized environment. Virtual servers can exist inside of a container or inside of a virtual machine. Containers can also run on virtual machines. Kubernetes has allowed developers to manage their multiple containers, whether those containers are running in VMs or on bare metal (servers without VMs).

As organizations expand their Kubernetes deployments, the overhead of those deployments is becoming a relevant concern. So-called “Kubesprawl” can occur within organizations due to a lack of best practices on when new clusters should be spun up or spun down, and when clusters should be shared by teams or shared by services.

Paul Czarkowski is a principal technologist with Pivotal. He joins the show to discuss virtualization, Kubernetes, and the state of the cloud native ecosystem.

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Kubernetes Virtualization with Paul Czarkowski", + "Episodes Uid": "SED8548984310", + "Episodes Audio File": "0fa5c9dc21b56e5f6a607ffa61f845b4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 360, + "Episodes ID": "f5da758a-e328-11ea-91a2-53ae697bbee2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/KafkaatNYT.mp3", + "Episodes Pubdate Date": "2017-10-30", + "Episodes Summary": "

The New York Times is a newspaper that evolved into a digital publication. Across its 166 year history, The Times has been known for longform journalistic quality, in addition to its ability to quickly churn out news stories. Some content on the New York Times is old but timeless “evergreen” content.

Readers of the New York Times website are not only looking for the most recent news–they want to know what the headlines were the day after Pearl Harbor. They want to read editorials about Martin Luther King. Over the last 30 years, New York Times has moved itself online, bringing old material with it.

Since the 90s, several different content management systems (CMS) have been used by journalists within The Times. These different sources of content store data in different formats.

This is a data management problem. Users want to search over the entire history of articles published by The Times, which means that The Times needs to unify those articles in a single index. These are articles from the 1920s that were digitized using OCR, articles from 1998 that were written on a legacy CMS, and articles from 2017 that use the latest CMS.

Boerge Svingen is the director of engineering at NYT, and he wrote about this problem and its solution on Medium. This story describes the flexibility of Kafka; in contrast to the applications of Kafka as a place to buffer high volumes of data, the New York Times uses Kafka as a place to unify data and allow for other specific materialized views to be built on top of it.

We have covered Kafka in the past with interviews of some of its creators–including Jay Kreps and Neha Narkhede. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kafka at NY Times with Boerge Svingen", + "Episodes Uid": "SED3975356081", + "Episodes Audio File": "280977e9194fc641e7376dd2e8d88925.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "tc", + "Episodes ID": "2ea41d12-e329-11ea-91a2-238bd6dc5e75", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/haseeb_poker_programming.mp3", + "Episodes Pubdate Date": "2015-10-23", + "Episodes Summary": "

Haseeb Qureshi is an former high-stakes poker player who pivoted to web development. He is an instructor at App Academy in San Francisco.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Poker to Programming with Haseeb Qureshi", + "Episodes Uid": "SED4560639989", + "Episodes Audio File": "abff19e28543e495f1b4ae8091ca2e0d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3mf", + "Episodes ID": "f3a6afea-e328-11ea-91a2-3bf09637964c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_04_PubsubInfrastructure.mp3", + "Episodes Pubdate Date": "2018-04-04", + "Episodes Summary": "

The pubsub pattern allows a developer to create channels, which messages can be written to and read from. Pubsub messaging is useful for multicast messaging–when you want to publish messages from a producer, and have multiple consumers who are subscribed to the publisher receive those messages. Almost any application that reaches a high level of complexity will need a pubsub system of some kind.

The pubsub system itself can be complex. A pubsub system needs to scale up and down to handle different numbers of consumers and producers, and different volumes of messages. Back in 2010, the growth of mobile and cloud was leading to many new applications with high throughput, multi-user interactions. Developers were standing up their own instances of open source pubsub message queueing systems like RabbitMQ and ZeroMQ. Once the MQ systems needed to scale, the developer would need to handle the scaling. Stephen Blum started his company PubNub around this time, to create automatically scaling APIs for messaging.

Stephen joins the show to discuss the infrastructure choices around building a large scale pubsub service, and how the company has scaled over time. He also talks about the management, product development, and business side of running the company. PubNub has built several additional technologies on top of the core infrastructure that was originally for messaging. Full disclosure: PubNub is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "PubSub Infrastructure with Stephen Blum", + "Episodes Uid": "SED8816841852", + "Episodes Audio File": "cc779b95221640a481e0d363ce3ab80b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3a3", + "Episodes ID": "f560910c-e328-11ea-91a2-73f46a80581a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Keyless.mp3", + "Episodes Pubdate Date": "2017-12-05", + "Episodes Summary": "

When I log into my bank account from my laptop, I first enter my banking password. Then the bank sends a text message to my phone with a unique code, and I enter that code into my computer to finish the login. This login process is two-factor authentication. I am proving my identity by entering my banking password (the first factor) and validating that I am in control of my phone (the second factor) by receiving that text message.

But in order to log in from my laptop, I need to be in control of my laptop. The laptop itself is a factor. With the laptop and my password, I have two factors. I might not actually need the phone as a factor.

Praneet Sharma is the CEO of Keyless, a product that moves 2-factor authentication into the browser. Praneet joins the show to discuss how all kinds of authentication work: multi-factor authentication, single sign on, and Yubikey. We use this discussion of authentication methods to help explain why it actually could make sense for some people to be doing 2-factor authentication without requiring people to take out their phone.

We also explore recent security breaches like Target, Equifax and Yahoo–and the industry of security software sold to developers. I see giant banners for security software companies every time I go into the San Francisco airport, and Praneet explained to me some of the products that these kinds of companies are selling.

Praneet has joined the show in a previous episode to talk about advertising fraud. He also works with Shailin Dhar at Method Media Intelligence.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Secure Authentication with Praneet Sharma", + "Episodes Uid": "SED5535259600", + "Episodes Audio File": "1a20946b2eca709eb7d6aaf03d837b15.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3aw", + "Episodes ID": "f5439b38-e328-11ea-91a2-cf92306034a3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CloudflareApps.mp3", + "Episodes Pubdate Date": "2017-12-12", + "Episodes Summary": "

Ten years ago, if you wanted to build software, you probably needed to know how to write code. Today, the line between “technical” and “non-technical” people is blurring.

Website designers can make a living building sites for people on WordPress or Squarespace–without knowing how to write code. Salesforce integration experts can help a sales team set up complicated software–without knowing how to write code. Shopify experts can set up an ecommerce store to your exact specifications–without knowing how to write code.

WordPress, Squarespace, Salesforce, and Shopify are all fantastic services–but they are not compatible with each other. I can’t install a WordPress plugin on Salesforce.

Now imagine this from the point of view of plugin creators. Plugin creators make easy ways to integrate different pieces of software together. Take PayPal as an example. PayPal wants to make it easy for software builders to integrate with their API.

One plugin that PayPal has is a button that says “Pay with PayPal.” If I am a developer at PayPal, and I am building a button that people should be able to easily put on their webpage so that their users can pay with PayPal, I have to create a button that is compatible with WordPress, and Squarespace, and Wix, and Weebly, and GoDaddy, and Blogger, and all the other website builders that I might want to integrate with.

In 2014, Zack Bloom started a company called Eager. Eager was a cloud app marketplace which allowed app developers to make flexible plugins that non-technical users could drag and drop into their site without technical expertise.

In order for these non-technical users to add any apps from the Eager marketplace to their webpage, they had to drop in a line of JavaScript–which is, unfortunately, a significant hurdle for a nontechnical user.

Eager proved to be a useful distribution mechanism for plugin developers who could write a plugin once and get distributed to multiple plugin marketplaces. But Eager was not as widely used as a way to directly drag and drop plugins onto sites.

The question was: how do you build a marketplace for non-technical users to add plugins to any website without forcing the non-technical user to write code? How do you make editing any website as easy as a WYSIWYG editor?

The CDN turns out to be the perfect distribution platform for these kinds of apps. Users already integrate with a CDN, so the CDN can do the work of inserting the code that allows the plugins to be added to a user’s webpage.

Because of the opportunity for the integration between a plugin marketplace and a CDN, Eager was acquired by Cloudflare, and Eager became Cloudflare apps. Zack Bloom joins the show today to discuss the motivations for his company, the engineering behind building a cloud app marketplace, and the acquisition process of his company Eager.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cloud Marketplace with Zack Bloom", + "Episodes Uid": "SED6023615251", + "Episodes Audio File": "a13e6f8d49ab3cd951e4a16e79a00dd9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "46d", + "Episodes ID": "f235aef4-e328-11ea-91a2-9b4135bc24d9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_17_GitVulnerability.mp3", + "Episodes Pubdate Date": "2018-07-17", + "Episodes Summary": "

Git is a distributed file system for version control. Git is extremely reliable, fast, and secure, owing to the fact that it is one of the oldest pieces of open source software. But even battle-tested software can have vulnerabilities. In this episode, we explore a subtle git vulnerability that could have potentially led to git users executing malicious scripts when they intended to simply pull a repository.

Today’s guest Edward Thomson is a program manager at Microsoft, and a maintainer of libgit2, a C implementation of git. He also writes about git and hosts the podcast All Things Git. He is passionate about git development, which gave me a deeper perspective on something that I just consider a tool. But the only reason that tool is so good–the only reason it fades into the background–is because there are people that are passionate enough to work on it on a regular basis.

We also spent some time talking about the vulnerabilities that can spread through shared code environments–particularly in the realm of git, npm, and PHP. And we touched on how deployment workflows around git and Kubernetes are changing. Full disclosure: Microsoft, where Edward works, is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Git Vulnerability with Edward Thomson", + "Episodes Uid": "SED4755599096", + "Episodes Audio File": "51a799dee585113abe42f4853dad33cc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5nl", + "Episodes ID": "ee4a417e-e328-11ea-91a2-bb3ad501ccfb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_30_ContainerPlatformSecurity.mp3", + "Episodes Pubdate Date": "2019-04-30", + "Episodes Summary": "

A Kubernetes instance occupies a wide footprint of multiple servers, creating an appealing target to an attacker, due to its access to a large pool of compute resources. A common attack against an exposed Kubernetes cluster is to take it over for the purposes of mining cryptocurrency. Thus it is important to keep a cluster secure.

The importance of security is magnified for a cloud provider. A cloud provider runs a managed Kubernetes service, which might be running thousands of Kubernetes clusters. If the cloud provider’s chosen distribution of Kubernetes contains a vulnerability, or if the Kubernetes instances are misconfigured, all of these clusters could be exposed to the same vulnerability.

Maya Kaczorowski works on the security of Google’s managed Kubernetes service GKE. In today’s show we discuss the attack surface of a managed Kubernetes service. Maya was previously on the show to talk about container security. This episode is a good companion to that one, as well as a previous show with Liz Rice about container security.

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Container Platform Security with Maya Kaczorowski", + "Episodes Uid": "SED5873931232", + "Episodes Audio File": "52a28c443594ae3e3af4978b4590fea6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3k6", + "Episodes ID": "f40e9588-e328-11ea-91a2-27ea5e7a0572", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_06_BitcoinsFuture.mp3", + "Episodes Pubdate Date": "2018-03-06", + "Episodes Summary": "

Joseph Bonneau is co-author of Bitcoin and Cryptocurrency Technologies, a popular textbook. At NYU, he works as an assistant professor exploring cryptography and security. His YouTube lessons teaching Bitcoin have hundreds of thousands of views. His material offers clear explanations of how Bitcoin works.

Since Joseph has a clear understanding of the objective facts around Bitcoin, he is the perfect person to ask about the more subjective topics: the common misunderstandings of Bitcoin; the governance tradeoffs between Ethereum and Bitcoin; proof of work vs. proof of stake.

Joseph believes that the early mainstream cryptocurrency solutions will be largely centralized—and that we are likely to move beyond Bitcoin to more efficient currencies. I enjoyed hearing his reasons behind this perspective.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Bitcoin’s Future with Joseph Bonneau", + "Episodes Uid": "SED9566606039", + "Episodes Audio File": "4b8c9b42e8599d8d5ad06f897799fb59.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "u8", + "Episodes ID": "2eec9812-e329-11ea-91a2-eb49e68221a5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/kudu_edited.mp3", + "Episodes Pubdate Date": "2015-10-21", + "Episodes Summary": "

Kudu is an open-source storage engine for the Hadoop ecosystem. It balances the advantages of both HDFS and HBase, by allowing for performant random-access queries while also providing fast writes and scans for analytics.

Todd Lipcon is a software engineer at Cloudera who leads the development of Kudu.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Kudu with Todd Lipcon", + "Episodes Uid": "SED2492272781", + "Episodes Audio File": "a6b511222577101e82f1827785cab2ec.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4vc", + "Episodes ID": "f0ae3614-e328-11ea-91a2-93462e23a0db", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_04_FOSSA.mp3", + "Episodes Pubdate Date": "2018-11-05", + "Episodes Summary": "

Open source software powers everything we do on the Internet. Google runs on Linux servers. Content sites are served by WordPress. Our data is queued in Kafka clusters and stored in MongoDB instances.

The success of an open source project often leads to the creator of that open source software becoming wealthy. An open source project can be monetized through enterprise add-ons, or consultation, or simplified hosting. The creators of open source software know their domains so well, that they are usually well-suited to operate this kind of open source business.

Open source business model success stories include Elastic (ElasticSearch), Cloudera (Hadoop), and Red Hat.

The rise in usage of cloud providers has changed the viability of some open source business models. AWS can monetize almost any open source project more profitably than the creators. This is because AWS has established distribution channels.

If I already run my application on AWS, and I am looking for someone to provide me with a hosted version of a database, I will probably choose the hosted database that AWS provides.

The Commons Clause is a license that open source projects can use to protect their code from being profited from. Redis, an open source in-memory object storage system, recently licensed their code with the Commons Clause with the goal of improving the business of Redis Labs, a company built by the creators of the Redis project.

Kevin Wang joins the show to discuss everything open source–from business models to security vulnerabilities to licensing. Kevin is the CEO at FOSSA, a system for managing open source licensing and security. Kevin was involved in the creation of the Commons Clause and has written about it in detail.

", + "Episodes Title": "Commons Clause with Kevin Wang", + "Episodes Uid": "SED1763704842", + "Episodes Audio File": "50d159097c27286864e1c7a2fcab350a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 576, + "Episodes ID": "efddb6f6-e328-11ea-91a2-7f543e22f013", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_09_CloudEvents.mp3", + "Episodes Pubdate Date": "2019-01-09", + "Episodes Summary": "

Functions-as-a-service allow developers to run their code in a “serverless” environment. A developer can provide a function to a cloud provider and the code for that function will be scheduled onto a container and executed whenever an event triggers that function.

An “event” can mean many different things. It is a signal that something has changed within your application. When you save a file to an Amazon S3 bucket, that creates an event. When a user signs up for your app, that can create an event.

Functions-as-a-service are allowing people to build applications completely out of managed cloud infrastructure. Apps can be fully “serverless”, with managed databases, queueing systems, and APIs tied together by event-triggered functions.

Today, there is not a consistent format for events across different applications and cloud providers. This makes it more difficult to stitch together events across these different environments. Ideally, events would be lightweight, easy to deserialize, and easy to interoperate with.

The Cloud Events specification is a project within the Cloud Native Computing Foundation with the goal of creating a standard format for events. Doug Davis is the CTO for developer advocacy of containers at Microsoft. He joins the show to discuss how events and event-based programming works, and the need for a common format across cloud events.

", + "Episodes Title": "Cloud Events with Doug Davis", + "Episodes Uid": "SED5933337850", + "Episodes Audio File": "5a0810032bc93f13582a79b5bd555e20.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ui", + "Episodes ID": "2ecb9928-e329-11ea-91a2-c7ccc5b7f1db", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/tarn_adams_post_audacity.mp3", + "Episodes Pubdate Date": "2015-10-22", + "Episodes Summary": "

Dwarf Fortress is a construction and management simulation computer game set in a procedurally generated fantasy world in which the player indirectly controls a group of dwarves, and attempts to construct a successful underground fortress.

Tarn Adams works on Dwarf Fortress with his brother Zach.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Dwarf Fortress with Tarn Adams", + "Episodes Uid": "SED2731724894", + "Episodes Audio File": "ada39494a0d89269e7dccdd01a225878.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3po", + "Episodes ID": "f33b7252-e328-11ea-91a2-7b3e12cfc0ab", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_03_WannaCryGrayHat.mp3", + "Episodes Pubdate Date": "2018-05-03", + "Episodes Summary": "

Last year, the WannaCry ransomware attack shut down hospitals, public transportation systems, and governments, demanding payment to unlock key computer systems. A programmer named Marcus Hutchins was able to stop WannaCry by registering a DNS entry buried in the WannaCry code.

Not long after he stopped the WannaCry attack, Marcus Hutchins was arrested at a security conference in Las Vegas. Marcus’s arrest was due to actions that were unrelated to WannaCry. He is accused of writing a piece of malware called Kronos.

Marcus volunteered his time to help stop WannaCry–a piece of ransomware that threatened to cause billions of dollars in damages. Whether or not he was a black hat in the past, perhaps Marcus should be absolved of his past actions.

Reeves Wiedeman is a journalist with New York Magazine, and he joins the show to tell the story of WannaCry’s Gray Hat: Marcus Hutchins.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "WannaCry’s Gray Hat with Reeves Wiedeman", + "Episodes Uid": "SED3476870269", + "Episodes Audio File": "727a09d0b9e568f49f152ac77cb74da3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2t3", + "Episodes ID": "f91c6762-e328-11ea-91a2-c71da327528a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/googleearlydays_edited.mp3", + "Episodes Pubdate Date": "2017-06-16", + "Episodes Summary": "

John Looney spent more than 10 years at Google. He started with infrastructure, and was part of the team that migrated Google File System to Colossus, the successor to GFS. Imagine migrating every piece of data on Google from one distributed file system to another.

In this episode, John sheds light on the engineering culture that has made Google so successful. He has very entertaining stories about clusterops and site-reliability engineering.

Google’s success in engineering is due to extremely high standards, and a culture of intellectual honesty. With the volume of data and throughput that Google responds to, 1-in-a-million events are likely to occur. There isn’t room for sloppy practices.

John now works at Intercom, where he is adjusting to the modern world of Google infrastructure for everyone. This conversation made me feel quite grateful to be an engineer in a time where everything is so much cheaper, so much easier, and so much more performant than it was in the days when Google first built everything from scratch.

I had a great time talking to John, and hope he comes back on the show again in the future because it felt like we were just scratching the surface of his experience.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Google Early Days with John Looney", + "Episodes Uid": "SED4707971123", + "Episodes Audio File": "9afbad2deaa51095fc58d9116fe631ad.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2v4", + "Episodes ID": "f750cd74-e328-11ea-91a2-1f0260cb0361", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CoinbaseAntifraud.mp3", + "Episodes Pubdate Date": "2017-07-13", + "Episodes Summary": "

Coinbase is a platform for buying and selling digital currency: bitcoin, ethereum, and litecoin. Every payments company deals with fraud, but a cryptocurrency company has a harder job than most payments companies, because bitcoin transactions are anonymous and non-reversible. This is in contrast to a bank, which deals with a regulated, reversible transaction system.

Soups Ranjan is the director of data science at Coinbase. In this episode, he walks through the challenges of preventing fraud and describes how machine learning and humans in the loop are used to deal with bad actors. From the data ingestion to the data engineering to the data science, this episode is a great overview of antifraud at Coinbase, and is a nice complement to the presentation that we previously aired from Soups.

This is the second episode in our series about Coinbase. Yesterday we discussed how Coinbase makes cryptocurrencies easier to work with. Tomorrow we dive into the security infrastructure of Coinbase. We’d love to hear your thoughts on this series, and any other suggestions or feedback you have. Send me an email–jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Coinbase Antifraud with Soups Ranjan", + "Episodes Uid": "SED7862655609", + "Episodes Audio File": "bf9bfa3a5f75541b1c892774ba8a01a4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "59k", + "Episodes ID": "efab464e-e328-11ea-91a2-336ab2033cb5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_24_TiDB.mp3", + "Episodes Pubdate Date": "2019-01-24", + "Episodes Summary": "

When a user interacts with an application to order a ride with a ridesharing app, the data for that user interaction is written to a “transactional” database. A transactional database is a database where specific rows need to be written to and read from quickly and consistently.

Speed and consistency are important for applications like a user ordering a car, and riding around in that car, because the user’s client is frequently communicating with the database to update their session. Other applications of a transactional database would include a database that backs a messaging system, a banking application, or document editing software.

The data from a transactional database is often reused in “analytic” databases. An analytic database can be used for performing large scale analysis, aggregations, averages, and other data science queries.

The requirements for an analytic database are different from a transactional database because the data is not being used for an active user session. To fill the data in an analytic database, the transactional data gets copied from the transactional database in a process called ETL.

The separation of the transaction data store from the analytic data store causes problems for data engineering. To address these problems, some newer databases combine transactional and analytic functionality in the same database. These databases are often called “NewSQL”.

TiDB is an open source database built on RocksDB and Kubernetes. TiDB is widely used in China by high volume applications such as bike sharing and massively multiplayer online games. Kevin Xu works at PingCAP, a company built around TiDB. He joins the show to talk about modern databases, distributed systems, and the architecture for TiDB.

", + "Episodes Title": "TiDB: Distributed NewSQL with Kevin Xu", + "Episodes Uid": "SED7480592224", + "Episodes Audio File": "bf25b1aeddcb816f172e1f1df02671c9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5fu", + "Episodes ID": "ef0dd33c-e328-11ea-91a2-0fa5e7083221", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_11_MicrogridSolutions.mp3", + "Episodes Pubdate Date": "2019-03-11", + "Episodes Summary": "

The demand for electricity is based on the consumption of the electrical grid at a given time. The supply of electricity is based on how much energy is being produced or stored on the grid at a given time. Because these sources of supply and demand fluctuate rapidly but predictably, energy markets present profit opportunities for traders.

Minh Dang and Corey Noone are engineers with Advanced Microgrid Solutions, a company that builds software to help traders capture better opportunities in the energy markets. Minh and Corey join the show to talk about how their company builds and deploys machine learning models for market prediction.

We discussed data infrastructure, machine learning model deployments, and the dynamics of the energy markets.

", + "Episodes Title": "Energy Market Machine Learning with Minh Dang and Corey Noone", + "Episodes Uid": "SED4018932995", + "Episodes Audio File": "fa2303a6eea37e1b2f2f50da659526ff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "44z", + "Episodes ID": "f254205a-e328-11ea-91a2-0f70749b643e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_09_Flutter.mp3", + "Episodes Pubdate Date": "2018-07-09", + "Episodes Summary": "

Flutter is a project from Google that is rebuilding user interface engineering from the ground up.

Today, most engineering teams have dedicated engineering resources for web, iOS, and Android. These different platforms have their own design constraints, their own toolset, and their own programming languages. But each platform is merely building a user interface. Why should development across these three user surfaces be so different?

This was the question that Eric Seidel was asking himself three years ago, when he co-founded the Flutter project. The Flutter project had a few rough starts, as the team tried to figure out exactly what layer of abstraction they were trying to provide.

Around that time, ReactJS and React Native were growing in popularity. Seeing the React projects provided some data points, and some inspiration. But Flutter takes a lower level approach to cross platform app development, by presenting a rendering layer and a runtime API that are interfacing with the hardware in the same way that OpenGL does.

In today’s episode, Eric joins the show to explain how the Flutter project came to life, and his lessons from starting an ambitious project that took several years to pick up steam. I enjoyed this episode because Flutter could have massive improvements for how quickly we can build apps–and also because Eric is a serious engineer and there are so many insights in this episode about computer science, software engineering, and project management.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Flutter with Eric Seidel", + "Episodes Uid": "SED9404675371", + "Episodes Audio File": "efc5fd8ac298186b814c6e1b7d3b65d9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6gt", + "Episodes ID": "eb7471ea-e328-11ea-91a2-b333f3a4349d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/indiehackers_edited.mp3", + "Episodes Pubdate Date": "2019-11-25", + "Episodes Summary": "

Originally published November 4, 2016

Indie Hackers is a website that profiles independent developers who have made profitable software projects, usually without raising any money. These projects make anywhere from a few hundred dollars a month to more than $100,000 as in the case with park.io, one of the services profiled by Indie Hackers.

Courtland Allen is the creator, engineer, and interviewer behind Indie Hackers. For each business that is profiled by Indie Hackers, Courtland conducts a short interview with the founder.

Courtland joins the show to discuss the changing trends that are making it easier to bootstrap a software business if you are a capable developer–or even if you are a nontechnical person who understands how software works. Since Courtland and I are both in the business of interviewing engineers, we had a lot to talk about, and this is a fantastic episode.

", + "Episodes Title": "Indie Hackers with Courtland Allen Holiday Repeat", + "Episodes Uid": "SED8888224445", + "Episodes Audio File": "d6e72382e99b4e7c583a5f2e7760756d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2kd", + "Episodes ID": "02be975e-e329-11ea-91a2-93e22b0446f7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/upstarts_edited.mp3", + "Episodes Pubdate Date": "2017-03-30", + "Episodes Summary": "

Big technology companies have so much going on at any given time that a journalist can tell any type of story they want to about it. Depending on what angle you observe the company from, you can write a story depicting that company as good, evil, growing, or about to crash. The truth only becomes apparent to outsiders with time.

Amazon’s culture and business strategy were detailed in The Everything Store, a 2013 book by Brad Stone. I read The Everything Store before working at Amazon, then I read it a second time after working at Amazon. The book is an accurate and balanced depiction of Amazon’s ethos.

Brad’s new book The Upstarts documents the rise of Uber and Airbnb, two companies with a similar controversial valence to Amazon.

It was a pleasure to speak to Brad because I admire his engrossing storytelling as an author and his strategic analysis as a business journalist. After discussing business and technology with him, we explored journalism–Brad is senior executive editor at Bloomberg.

", + "Episodes Title": "Amazon and Uber with Brad Stone", + "Episodes Uid": "SED7780773990", + "Episodes Audio File": "a4b84fe8a3b0f284dd698fb6227cec52.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5vu", + "Episodes ID": "ed826226-e328-11ea-91a2-3b3afabca47d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_27_LambdaSchoolCurriculum.mp3", + "Episodes Pubdate Date": "2019-06-27", + "Episodes Summary": "

Programmers are in high demand, and software engineering is a career path that is fun, creative, and lucrative. There are many people who want to transition into a career in software and are looking for the right path toward writing code.

The traditional college computer science curriculum teaches some software engineering skills, but the time and financial cost of attending a university is prohibitive for many people who want to learn to code.

Over the past decade, there have been several new models for software education. 

Online video platforms such as Udacity and Coursera put computer science courses online to be watched at the viewer’s convenience. Online schools such as Free Code Camp allow someone to learn how to program without any experience, and with no financial payment. Boot camps with income-sharing agreements such as App Academy create an in-person education environment that mimics a university, but with better cost structure and incentive alignment.

Lambda School is an education system that takes elements of other software education models and combines them with newer SaaS technologies such as Slack and Zoom videoconferencing. Lambda School is an online software engineering curriculum with an income sharing agreement.

“Income sharing agreement” means that the student does not pay for their education until they get a job. With this model, the student can pay back Lambda School after their software engineering education gets them a high-paying software engineering job.

Andrew Madsen works at Lambda School, and he joins the show to describe the path that a student takes through Lambda School, the school’s curriculum for software education, and how Lambda School differs from the other options for coding education.

", + "Episodes Title": "Lambda School Education with Andrew Madsen", + "Episodes Uid": "SED6697909185", + "Episodes Audio File": "0d4656699ad36dd9d7193b063c6edb55.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3bu", + "Episodes ID": "f521bcc0-e328-11ea-91a2-7344da2965e0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ReactComponents.mp3", + "Episodes Pubdate Date": "2017-12-21", + "Episodes Summary": "

Modern frontend development is about components. Whether we are building an application in React, Vue, or Angular, components are the abstractions that we build our user interfaces out of. Today, this seems obvious, but if you think back five years ago, frontend development was much more chaotic–partly because we had not settled around this terminology of the component.

React has become the most popular frontend framework, and part of its growth is due to the ease and reusability of components across the community. It’s easy to find building blocks that you can use to piece together your frontend application. Do you need a video player component? Do you need a news feed component? A profile component? All of these things are easy to find.

As you build a React application, you take some open source components off the shelf, and you build others yourself. To keep things looking nice and consistent, you need to style your components. If you are not careful with how you manage your stylesheets, you can end up with inconsistent stylings and namespace conflicts.

Max Stoiber is the creator of styled-components, a project to help enforce best practices around styling components. He has also a founder of Spectrum, a system that allows people to build online communities. Spectrum has similar design and engineering challenges to Slack or Facebook, so it made for a great discussion of modern software architecture.

In today’s episode, Max and I had a wide-ranging conversation about frontend frameworks, components, and the process of building a product. Max also describes the advantages of using GraphQL and the Apollo toolchain.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "React Components with Max Stoiber", + "Episodes Uid": "SED2411212422", + "Episodes Audio File": "6d8631e8a920cbd4c5dd7f1b30b7b452.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5aj", + "Episodes ID": "ef866a40-e328-11ea-91a2-8b9ca419838d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_04_Hashicorp.mp3", + "Episodes Pubdate Date": "2019-02-04", + "Episodes Summary": "

Hashicorp was founded seven years ago with the goal of building infrastructure tools for automating cloud workflows such as provisioning, secret management, and service discovery. Hashicorp’s thesis was that operating cloud infrastructure was too hard: there was a need for new tools to serve application developers.

Hashicorp founders Mitchell Hashimoto and Armon Dadgar began releasing open source tools to fulfill their vision of better automation. Terraform, Vagrant, Consul, and other tools created by Hashicorp gained popularity, and Hashicorp began iterating on their business model. Today, Hashicorp makes money by offering enterprise features and support to enterprises such as Pinterest, Adobe, and Cruise Automation.

Over the last seven years, enterprise software infrastructure has changed rapidly. First, enterprises moved from script-based infrastructure automation to container orchestration frameworks. Then, the container orchestration world consolidated around Kubernetes.

Today, large enterprises are rapidly adopting Kubernetes with a mix of public cloud and on-prem vendors. At the same time, these enterprises are also becoming more willing to consume proprietary tools from the public cloud providers.

Hashicorp has benefitted from all of this change. Their different tools fit into a variety of workflows, and are not closely coupled with any particular cloud provider or platform solution.

Armon and Mitchell join today’s show to discuss the business model and the product philosophy of Hashicorp. We also touch on service mesh, zero trust networking, and their lessons from the container orchestration wars.

", + "Episodes Title": "Scaling Hashicorp with Armon Dagdar and Mitchell Hashimoto", + "Episodes Uid": "SED3064668661", + "Episodes Audio File": "3c3276ed7c9c9f8b67dd7568b3327f83.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2hx", + "Episodes ID": "06404c42-e329-11ea-91a2-3b32676c0907", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Convergence_edited.mp3", + "Episodes Pubdate Date": "2017-02-24", + "Episodes Summary": "

At the first Software Engineering Daily Meetup, the speakers explored a range of topics. A few weeks ago, we published Courtland Allen’s talk about how to build a small software business. In today’s episode, we are publishing Haseeb Qureshi’s talk, called “Everything That Rises Must Converge: Why Engineers Disagree About Everything (And Why Fraudsters Do Too).”

This talk explores philosophy, poker, software engineering, fraud, and a basket of other topics. These topics might sound like a random collection, but Haseeb currently works as an engineer on Airbnb’s Risk team and he is the author of How To Be a Poker Player, which is a book on the philosophy of poker.

The audio is taken from the Meetup and we cleaned it up as best we could. We will do a better job with the audio from the next Meetup–which is Thursday, March 9th at Galvanize! Check out our Meetup page for more details.

", + "Episodes Title": "Convergence with Haseeb Qureshi", + "Episodes Uid": "SED3700428038", + "Episodes Audio File": "e134b9b18878a54cd38054a8326b1c11.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3na", + "Episodes ID": "f3a21fac-e328-11ea-91a2-071c210aad40", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_05_EthereumGovernance.mp3", + "Episodes Pubdate Date": "2018-04-05", + "Episodes Summary": "

The Ethereum community started as a small group of dedicated engineers. It has ballooned to thousands of engineers, entrepreneurs and investors, all of whom have a stake in the direction of Ethereum. Ethereum is an open source project, and the direction of a popular open source project can get complex.

Ethereum is figuring out how to govern itself. It’s not clear what the perfect model is, but there are a few historical examples to think about: namely Linux and Bitcoin.

Linux is similar to Ethereum in that there is a clear leader—Linux has Linus Torvalds and Ethereum has Vitalik Buterin. Linux is massively successful, and the Linux development team does have a top-down, hierarchical approach. But does a hierarchy with clear leadership make sense for a project like Ethereum, which has decentralization at its core?

Bitcoin is headless—Satoshi disappeared in 2010, and there is not an official leader. Bitcoin has succeeded without a well-defined hierarchy–depending on what your definition of success is. Bitcoin development does not move as fast as Ethereum (this is by design)—but there is more widespread trust that the integrity of the system cannot be compromised by its creator.

Hudson Jameson is an Ethereum developer and entrepreneur who has been part of the community since the early days. He works on Ethereum governance, which defines how changes to the Ethereum project are proposed, accepted, and implemented. Hudson joins the show today to talk about Ethereum governance, smart contracts, and the DAO hack. We did not discuss on-chain vs. off-chain governance, but I am hoping to cover that in a future episode.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Ethereum Governance with Hudson Jameson", + "Episodes Uid": "SED9321861249", + "Episodes Audio File": "90dbef19a907720278e16618900978d9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4bm", + "Episodes ID": "f1bd3a5a-e328-11ea-91a2-df838742904d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_14_Stackdriver.mp3", + "Episodes Pubdate Date": "2018-08-14", + "Episodes Summary": "

At Google, the job of a site reliability engineer involves building tools to automate infrastructure operations. If a server crashes, there is automation in place to create a new server. If a service starts to receive a high load of traffic, there is automation in place to scale up the instances of that service.

In order to create an automated response to an infrastructure problem, a site reliability engineer needs insights into that infrastructure. Every service needs tools around monitoring, alerting, debugging, and distributed tracing.

One benefit of working at a large company like Google is that an engineer building a new product gets this kind of tooling by default. If I am hacking on a project at home, I have to set up all kinds of tools to help me diagnose and resolve problems. Setting up this tooling takes time, and requires expertise.

Stackdriver is a set of tools and instrumentation that allows developers to monitor, debug, and inspect infrastructure. Stackdriver is based on the internal observability tools built for Google. Mark Carter is a group product manager at Google, and he joins the show to discuss site reliability engineering and the creation of Stackdriver.

", + "Episodes Title": "Infrastructure Monitoring with Mark Carter", + "Episodes Uid": "SED4411996764", + "Episodes Audio File": "a071b20e462bc502ef9187992937da13.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48r", + "Episodes ID": "f1af255a-e328-11ea-91a2-a7d56f5d226d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_17_WebAssemblyFuture.mp3", + "Episodes Pubdate Date": "2018-08-17", + "Episodes Summary": "

WebAssembly is a low-level compilation target for any programming language that can be interpreted into WebAssembly. Alternatively, WebAssembly is a way to run languages other than JavaScript in the browser. Or, yet another way of describing WebAssembly is a virtual machine for executing code in a low level, well-defined sandbox.

WebAssembly is reshaping what is possible to do in the web browser. A developer can write a program in Rust or C++, compile it down into a WebAssembly module, and call out to that module via JavaScript. This is very useful for running memory-sensitive workloads in the browser—such as 3-D games.

But WebAssembly is also useful for running modules outside of the browser. Why is that important? If you can already run C++ or Rust code outside of the browser by executing the program from the command line, why would you want to put the code into a WebAssembly module before executing it? One answer is security. WebAssembly modules have well-defined semantics for what memory they can access. WebAssembly could provide more reliable sandboxing for untrusted code.

Steve Klabnik is a software engineer at Mozilla, and he joins the show today to play the role of a WebAssembly futurist. We revisit the basics of WebAssembly and the current state of the technology. Steve talks Steve also describes the lessons of past web technologies such as Flash—and what they did right and wrong. We also explore the current and future applications of WebAssembly, which we will talk about in more detail in tomorrow’s episode.

", + "Episodes Title": "WebAssembly Future with Steve Klabnik", + "Episodes Uid": "SED1594527607", + "Episodes Audio File": "a8a393dd52fabe467066fc38ca7d6fe9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3xg", + "Episodes ID": "f2c3106e-e328-11ea-91a2-572a57a02612", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_06_ContainerStorageInterface.mp3", + "Episodes Pubdate Date": "2018-06-06", + "Episodes Summary": "

A database stores data to an underlying section of storage. If you are an application developer, you might think of your persistent storage system as being the database itself–but at a lower level, that database is writing to block storage, file storage, or object storage.

A container orchestration system manages application containers. If you want to run WordPress (a blogging platform) on Kubernetes, that means you also need to run a database to store your blog posts in a persistent way. To run a database, you need to have an underlying storage medium–which could be a disk that is at your on-prem data center, or block storage on a disk at a cloud provider.

Kubernetes is not the only container orchestrator. There’s also Cloud Foundry, Mesos, Docker Swarm, and several others. Each of these container orchestrators needs to be able to run a variety of persistent workloads (such as a MySQL database or a Kafka cluster). Each of these persistent workloads needs to be able to use different types of backing storage.

With the range of container orchestrators and the range of backing storage types, a problem arises. Every storage type would have to write custom code to connect to each container orchestrator.

The solution to this is the CSI: the container storage interface. The CSI is an interface layer between the container orchestrator and the backing storage system. In today’s episode, Jie Yu from Mesosphere describes the motivation for the CSI, and gives an overview for its design principles. There are great lessons here for anyone working with containers or distributed systems in general.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Container Storage with Jie Yu", + "Episodes Uid": "SED1711347753", + "Episodes Audio File": "c4d94636445d0a2f2d825674b5a744f4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3fw", + "Episodes ID": "f49c23b2-e328-11ea-91a2-53312433abf2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_26_EdgeDeepLearning.mp3", + "Episodes Pubdate Date": "2018-01-26", + "Episodes Summary": "

A modern farm has hundreds of sensors to monitor the soil health, and robotic machinery to reap the vegetables. A modern shipping yard has hundreds of computers working together to orchestrate and analyze the freight that is coming in from overseas. A modern factory has temperature gauges and smart security cameras to ensure workplace safety.

All of these devices could be considered “edge” devices.

Over the last decade, these edge devices have mostly been used to gather data and save it to an on-premise server, or to the cloud. Today, as the required volumes of data and compute scale, we look for ways to better utilize our resources. We can start to deploy more application logic to these edge devices, and build a more sophisticated relationship between our powerful cloud servers and the less powerful edge devices.

The soil sensors at the farm are recording long time series of chemical levels. The pressure sensors in a centrifuge are recording months and years of data. The cameras are recording terabytes of video. These huge data sets are correlated with labeled events–such as crop yields.

With these large volumes of data, we can construct models for responding to future events. Deep learning can be used to improve systems over time. The models can be trained in the cloud, and deployed to devices at the edge.

Aran Khanna is an AI engineer with Amazon Web Services, and he joins the show to discuss workloads at the cloud and at the edge–how work can be distributed between the two places, and the tools that can be used to build edge deep learning systems more easily.

To find all of our shows about machine learning and edge computing, as well as links to learn more about the topics described in the show, download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Edge Deep Learning with Aran Khanna", + "Episodes Uid": "SED9788910377", + "Episodes Audio File": "792375e9e2ee5106cb0d53c1b1205945.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 601, + "Episodes ID": "ecfd00d6-e328-11ea-91a2-f3a93d24b397", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_30_WebAssemblyonIoT.mp3", + "Episodes Pubdate Date": "2019-07-30", + "Episodes Summary": "

“Internet of Things” is a term used to describe the increasing connectivity and intelligence of physical objects within our lives. 

IoT has manifested within enterprises under the term “Industrial IoT,” as wireless connectivity and machine learning have started to improve devices such as centrifuges, conveyor belts, and factory robotics. In the consumer space, IoT has moved slower than many people expected, and it remains to be seen when we will have widespread computation within consumer devices such as microwaves, washing machines, and lightswitches.

IoT computers have different constraints than general purpose computers. Security, reliability, battery life, power consumption, and cost structures are very different in IoT devices than in your laptop or smartphone. One technology that could solve some of the problems within IoT is WebAssembly, a newer binary instruction format for executable programs.

Jonathan Beri is a software engineer and the organizer of the San Francisco WebAssembly Meetup. He has significant experience in the IoT industry, and joins the show to discuss the state of WebAssembly, the surrounding technologies, and their impact on IoT.

", + "Episodes Title": "WebAssembly on IoT with Jonathan Beri", + "Episodes Uid": "SED9391561689", + "Episodes Audio File": "bcc2442e1d7ab030d14e91f47137128e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "34i", + "Episodes ID": "f6126486-e328-11ea-91a2-371dd3823ffe", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Gigster.mp3", + "Episodes Pubdate Date": "2017-10-13", + "Episodes Summary": "

You have heard the phrase: every company is becoming a software company. An insurance company is now supposed to turn into a software company that sells insurance. A clothing retailer needs to reinvent itself to be able to build software to manage the production and distribution of its clothing.

Software applications provide so much leverage to an organization, it seems smart to develop in-house software teams to build those applications. But does it really make sense? Is there a better alternative?

In the 90s outsourcing was a common solution to this problem. If you didn’t have software expertise at your company, you would hire a large consulting firm. These firms would often hire inexperienced offshore developers, and the resulting code quality was not so great.

Because of the bad experiences of the first Internet boom, companies became more cautious about outsourcing their engineering work–which led to today, where the standard is to hire your own software team.

The world has changed in ways that have made outsourcing a more viable solution.

Programming best practices are more widely understood. There is an international community of software engineers that share information on places like Stack Overflow, Quora, and Twitter.  Off-the-shelf collaboration tools make it much easier to communicate the requirements of a project to a team of developers.

Gigster is a company that is working to optimize the engineering of software projects. Large enterprises come to Gigster to build new projects from scratch–whether that project is a marketplace, a mobile application, or a machine learning model. Roger Dickey is the CEO of Gigster, and he joins the show to describe how Gigster works, and why it often makes sense for companies to focus on their core competency and outsource software engineering.

Some of our most popular episodes of Software Engineering Daily describe how leading software companies are being built–we have covered Giphy, Netflix, Digital Ocean, Stripe, and many others.  Download the Software Engineering Daily app for iOS or Android to hear all of our old episodes. They are easily organized by category, and as you listen, the SE Daily app gets smarter, and recommends you content based on the episodes you are hearing. If you don’t like this episode, you can easily find something more interesting by using the recommendation system.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! We are building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend–and more projects are coming soon. If you have ideas for how software engineering media content should be consumed, or if you are interested in contributing code, check out github.com/softwareengineeringdaily, or join our Slack channel (there’s a link on our website)–or send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Gigster with Roger Dickey", + "Episodes Uid": "SED7657737613", + "Episodes Audio File": "3184512f6538f3295df886d8c85b6e16.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3jg", + "Episodes ID": "f42d26b0-e328-11ea-91a2-63bbb6e9fdad", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_26_SparkDelta.mp3", + "Episodes Pubdate Date": "2018-02-26", + "Episodes Summary": "

Apache Spark is a system for processing large data sets in parallel. The core abstraction of Spark is the resilient distributed dataset (RDD), a working set of data that sits in memory for fast, iterative processing.

Matei Zaharia created Spark with two goals: to provide a composable, high-level set of APIs for performing distributed processing; and to provide a unified engine for running complete apps.

High-level APIs like SparkSQL and MLlib enable developers to build ambitious applications quickly. A developer using SparkSQL can work interactively with a huge dataset, which is a significant improvement on batch Hive jobs running on Hadoop. A developer training a machine learning model can put the model through multiple steps in the training process without checkpointing the data to disk.

The second goal of Spark–a “unified engine for running complete apps”–was the focus of my conversation with today’s guest Matei Zaharia.

Matei is the CTO of Databricks, a company that was started to implement his vision for Spark and to build highly usable products on top of the technology. Databricks Delta is a project that combines a data warehouse, data lake, and streaming system–all sitting on top of Amazon S3 and using Spark for processing.

In our recent episodes about streaming, we explored some common streaming architectures. A large volume of data comes into the system and is stored in Apache Kafka. Backend microservices and distributed streaming frameworks read that data and store it in databases and data lakes. A data warehouse allows for fast access to the large volumes of data–so that machine learning systems and business analysts can work with data sets interactively.

The goal of Databricks Delta is to condense the streaming system, the data lake, and the data warehouse into a single system that is easy to use. If you listened to the previous episodes, you will have an idea for the level of complexity that is involved in managing these different systems.

For some companies, it makes complete sense to manage a Kafka cluster, a Spark cluster, a set of S3 buckets, and a data warehouse like Amazon Redshift. But we probably don’t want all of that management to the lowest barrier to entry. Delta will hopefully reduce that barrier to entry and make it easier for enterprises to set up large systems for processing data.

A few notes before we get started. We just launched the Software Daily job board. To check it out, go to softwaredaily.com/jobs. You can post jobs, you can apply for jobs, and it’s all free. If you are looking to hire, or looking for a job, I recommend checking it out. And if you are looking for an internship, you can use the job board to apply for an internship at Software Engineering Daily.

Also, Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Spark and Streaming with Matei Zaharia", + "Episodes Uid": "SED6560320951", + "Episodes Audio File": "ea785806b7c5afdd303a6208ceb437e5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5tl", + "Episodes ID": "edbe9700-e328-11ea-91a2-b7dfa82cda6f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_10_KubernetesStoragewithSaadAli.mp3", + "Episodes Pubdate Date": "2019-06-10", + "Episodes Summary": "

Containers are made to fail gracefully. When your container shuts down due to a hardware or software failure, your distributed application should be able to tolerate that failure. One simple way to be able to tolerate such a failure is to make all of your application logic “stateless.”

If your application does not maintain state, then shutting it down in the middle of a computation is not a problem–you can just restart the application, restart your computation, and get the same result.

But applications need to maintain state. We need to use databases and in-memory systems to manage long-lived user sessions and other interactions. A database is not just an on-disk abstraction–a database requires an application server to be accepting network traffic. We can run those database applications within containers.

There is a fundamental tension between stateful applications and the idea that containers are meant to tolerate failure gracefully.

Saad Ali is an engineer at Google, and he returns to the show to discuss Kubernetes storage and state management. He gave a keynote at KubeCon EU, which I spoke to him about.

New Software Daily app for iOS. You can become a paid subscriber for ad free episodes at softwareengineeringdaily.com/subscribe

", + "Episodes Title": "Kubernetes Storage with Saad Ali", + "Episodes Uid": "SED6824215023", + "Episodes Audio File": "5952a11d7f77320eae20fcc09ba63be2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4qj", + "Episodes ID": "f0efe78a-e328-11ea-91a2-877a6d23b071", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_17_AzureSearch.mp3", + "Episodes Pubdate Date": "2018-10-17", + "Episodes Summary": "

Search is part of almost every application. Users search for movies to watch. Engineers search through terabytes of log messages to find exceptions. Drivers search through maps to find a destination. Search remains an unsolved problem, with lots of room for optimization.

Many search applications have been built Elasticsearch, an open source distributed search engine. Elasticsearch is the code that powers some search-as-a-service products offered by major cloud providers. After eight years of open source development, Elasticsearch is excellent at core search functionalities, such as indexing data, sharding, and serving queries.

With improved access to machine learning tools, search applications can advance in new and interesting ways. For example, an incoming search query can be sent to an API for natural language processing before being served by the search engine. A natural language processing API can derive additional meaning from the query, adding metadata to a search query. Machine learning can also be applied to better understand how people are searching across your search index, and to optimize the search index to incorporate those user preferences.

Liam Cavanagh is the principal program manager on Azure Search. He joins the show to talk about the architecture of a search index, how search queries are served by an index, and how machine learning APIs can be used to improve queries.

", + "Episodes Title": "Cloud Search with Liam Cavanagh", + "Episodes Uid": "SED6752648776", + "Episodes Audio File": "6bb6e87fd7e0b97058e91ae73d4289b9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "59d", + "Episodes ID": "efafa4c8-e328-11ea-91a2-8f12b60e4786", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_23_Storybook.mp3", + "Episodes Pubdate Date": "2019-01-23", + "Episodes Summary": "

React, Vue, and Angular are the most popular frontend JavaScript frameworks. Each of these frameworks lets frontend developers build components. A component is a high level visual abstraction that is used to compose a user interface.

Frontend development has moved towards component-driven-development. At a typical technology company, a designer will put together a design file of different user interface elements, and the frontend engineer will take those UI elements and program code that can render those designs as components. As organizations have started to reuse their components and share them across the organization, the efficiency of design and frontend engineering is improving.

User interface is gaining more of an emphasis with organizations and new tools are allowing frontend engineers and designers to work together more productively. One of these tools is Storybook, a system for sharing components and the code that renders those components.

Zoltan Olah joins the show to talk about Storybook, and his company Chroma. Chroma is building tools to allow design-driven teams to work more effectively. We talked about how the relationship of designers and frontend engineers has some resemblance to the relationship between “dev” and “ops” before the DevOps movement. There are some frictions in the process of moving between design and engineering implementation, and in talking to Zoltan, I got an understanding for how much the UI layer could improve through better tooling.

", + "Episodes Title": "Storybook: UI Engineering with Zoltan Olah", + "Episodes Uid": "SED7166141340", + "Episodes Audio File": "cad1ec3bf953bd7dcdb20581b90cd7f1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6hk", + "Episodes ID": "eb53bac2-e328-11ea-91a2-ff9bde9a3c67", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_04_HerokuInfrastructure.mp3", + "Episodes Pubdate Date": "2019-12-04", + "Episodes Summary": "

A cloud provider gives a developer low-cost compute infrastructure on-demand. 

Cloud providers can be divided up into two categories: Layer 1 cloud providers and Layer 2 cloud providers. A Layer 1 cloud provider such as Amazon Web Services owns server hardware and sells compute infrastructure as a commodity. A Layer 2 cloud provider purchases compute infrastructure from a Layer 1 provider and builds a high quality developer experience on top of that compute infrastructure.

Heroku was the first Layer 2 cloud provider. Heroku’s first business was to provide a high quality developer experience and low cost containerization infrastructure on top of Amazon’s EC2 virtual machine infrastructure. Heroku has added features for continuous integration, relational databases, caches, and queueing.

Building a Layer 2 cloud provider is a very different challenge than building a Layer 1 cloud provider. A Layer 1 provider must focus on low level problems such as hardware infrastructure and virtualization. This does not leave much time for focusing on developer experience. A Layer 1 cloud provider must be able to serve every type of potential software customer. A Layer 2 provider can provide a streamlined experience.

Mark Turner is an engineer at Heroku. He joins the show to discuss the architecture and engineering of a Layer 2 cloud provider. Heroku is built on top of Amazon Web Services, and the core compute infrastructure is built on top of a pool of EC2 virtual machines that are continually scheduled with applications that users create on Heroku. Full disclosure: Heroku is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Heroku Infrastructure with Mark Turner", + "Episodes Uid": "SED4451813387", + "Episodes Audio File": "9f131d84b66f96fdfd4509f84ba06e00.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6zf", + "Episodes ID": "ea0df15a-e328-11ea-91a2-d3a01531c3fd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_23_GoogleCloudNetworking.mp3", + "Episodes Pubdate Date": "2020-03-23", + "Episodes Summary": "

A large cloud provider has high volumes of network traffic moving through data centers throughout the world. These providers manage the infrastructure for thousands of companies, across racks and racks of multitenant servers, and cables that stretch underseas, connecting network packets with their destination.

Google Cloud Platform has grown steadily into a wide range of products, including database services, machine learning, and containerization. Scaling a cloud provider requires both technical expertise and skillful management.

Lakshmi Sharma is the director of product management for networking at Google Cloud Platform. She joins the show to discuss the engineering challenges of building a large scale cloud provider, including reliability, programmability, and how to direct a large hierarchical team.

We’re looking for new show ideas, so if you have any interesting topics, please feel free to reach out via twitter or email us at  jeff@softwareengineeringdaily.com

", + "Episodes Title": "Google Cloud Networking with Lakshmi Sharma", + "Episodes Uid": "SED6693552041", + "Episodes Audio File": "14e21c6c868ba344d81066a09a963b81.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ay", + "Episodes ID": "251faa72-e329-11ea-91a2-abbc2b8604fc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Drill_Edited.mp3", + "Episodes Pubdate Date": "2016-01-20", + "Episodes Summary": "

Apache Drill is a schema­-free SQL query engine for Hadoop, NoSQL, and cloud storage. Drill is unique in that it uses a JSON data model instead of a relational model like many traditional engines. Additionally, it supports on-the-fly schema discovery, which allows execution to begin without knowing the structure of the data. As a result, Drill can work with data that is constantly updating or changing.

Tomer Shiran is the founder of the Apache Drill project and the CEO of Dremio.

", + "Episodes Title": "Apache Drill with Tomer Shiran", + "Episodes Uid": "SED3700459472", + "Episodes Audio File": "f2339ff36ef1106a4ccba7d307332e6c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "69s", + "Episodes ID": "ec2ac616-e328-11ea-91a2-ef22d103e6a0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_02_FiveTranwithGeorge.mp3", + "Episodes Pubdate Date": "2019-10-02", + "Episodes Summary": "

Large companies have multiple databases, multiple data formats, and multiple applications that need to use the data. Every data engineer needs to move data between these different components of a system. Moving data between different parts of a system is often called “ETL”, an acronym for “Extract, Transform, Load.”

Data engineers spend much of their time writing code for ETL. This ETL code often moves data from a source such as a distributed file system into a data warehouse such as Amazon Redshift. ETL code also is used to take data out of platforms such as Google Analytics, and put that data into a system where it can be joined with internal data sets.

George Fraser is the CEO of Fivetran, a company that builds data connectors to improve the data engineering process. George joins the show to discuss modern data warehousing, and the business of building Fivetran. Data connectors may sound like a simple or trivial product, but it turns out to be a gigantic opportunity.

", + "Episodes Title": "Fivetran: Data Connectors with George Fraser", + "Episodes Uid": "SED6304307605", + "Episodes Audio File": "293063d2b443c36df6887289dded0308.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 779, + "Episodes ID": "e954d42c-e328-11ea-91a2-dfecda46050b", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_14_NovaCredit.mp3", + "Episodes Pubdate Date": "2020-05-14", + "Episodes Summary": "

A credit score is a rating that allows someone to qualify for a line of credit, which could be a loan such as a mortgage, or a credit card. We are assigned a credit score based on a credit history, which could be related to work history, rental payments, or loan repayments. 

One problem with the credit scoring system is that it is not internationalized. If I am coming from Brazil, I have a rental history of someone from Brazil. That information does not get naturally ported over to the United States. There needs to be a system for translating a foreign credit history to a US credit history.

Nova Credit is a company that makes a credit passport–a system for allowing users in one geographic location to use the credit history that they have built up to have credit in another location, namely the United States. Brian Regan and Misha Esipov work at Nova Credit, and they join the show to talk about how the company works, and the problem it solves.

", + "Episodes Title": "International Consumer Credit Infrastructure with Brian Regan and Misha Esipov", + "Episodes Uid": "SED1692638212", + "Episodes Audio File": "fc7d3153d71f157623b9a6a1fd070c13.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ai", + "Episodes ID": "e8f91d6c-e328-11ea-91a2-7b4a85aa96f2", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_10_AirflowAstronomer.mp3", + "Episodes Pubdate Date": "2020-06-10", + "Episodes Summary": "

Apache Airflow was released in 2015, introducing the first popular open source solution to data pipeline orchestration. Since that time, Airflow has been widely adopted for dependency-based data workflows. A developer might orchestrate a pipeline with hundreds of tasks, with dependencies between jobs in Spark, Hadoop, and Snowflake.

Since Airflow’s creation, it has powered the data infrastructure at companies like Airbnb, Netflix, and Lyft. It has also been at the center of Astronomer, a startup that helps enterprises build infrastructure around Airflow. Airflow is used to construct DAGs–directed acyclic graphs for managing data workflows.

Maxime Beauchemin is the creator of Airflow. Vikram Koka and Ash Berlin-Taylor work at Astronomer. They join the show to talk about the state of Airflow–the purpose of the project, its use cases, and open source ecosystem.

", + "Episodes Title": "Apache Airflow with Maxime Beauchemin, Vikram Koka, and Ash Berlin-Taylor", + "Episodes Uid": "SED1360263823", + "Episodes Audio File": "3c44d803e3fca52452fb95006f219656.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7fl", + "Episodes ID": "e881ba9c-e328-11ea-91a2-e74860702581", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_15_GithubMobile.mp3", + "Episodes Pubdate Date": "2020-07-15", + "Episodes Summary": "

GitHub has been a social network for developers for many years. Most social networks are centered around mobile applications, but GitHub sits squarely in a developer’s browser-based desktop workflow. As a result, the design of a mobile app for GitHub is less straightforward. GitHub did acquire a popular mobile client called GitHawk, which was developed by Ryan Nystrom.

Since joining GitHub, Ryan has worked on a new mobile app for GitHub, along with a team of engineers including Brian Lovin. Ryan and Brian both join the show to discuss GitHub mobile, and how they designed, architected, and built the app.

There is no company quite like GitHub–a social network combined with a version control system that provides a critical utility. All this made for an interesting episode about a one-of-a-kind mobile product.

", + "Episodes Title": "GitHub Mobile with Brian Lovin and Ryan Nystrom", + "Episodes Uid": "SED7208324728", + "Episodes Audio File": "9cd2c78b3f596f215e5922a074b01281.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6yx", + "Episodes ID": "ea2495f4-e328-11ea-91a2-6f634b5dbfdd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_16_SafeGraph.mp3", + "Episodes Pubdate Date": "2020-03-16", + "Episodes Summary": "

Physical places have a large amount of latent data. Pick any location on a map, and think about all of the questions you could ask about that location. What businesses are at that location? How many cars pass through it? What is the soil composition? How much is the land on that location worth?

The world of web-based information has become easy to query. We can use search engines like Google, as well as APIs like Diffbot and Clearbit. Today, the physical world is not so easy to query, but it is becoming easier. Location data as a service is a burgeoning field, with some vendors offering products for satellite data, foot traffic, and other specific location-based domains.

SafeGraph is a company that provides location data-as-a-service. SafeGraph data sets include data about businesses, patterns describing human movement, and geometric representations describing the shape and size of buildings. Ryan Fox Squire develops data products for SafeGraph, and he joins the show to talk about the engineering and strategy that goes into building a data-as-a-service company.

", + "Episodes Title": "Location Data with Ryan Fox Squire", + "Episodes Uid": "SED5616784934", + "Episodes Audio File": "8c3a320ed11eaf3a54a785229650dec2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ym", + "Episodes ID": "ea16e486-e328-11ea-91a2-2347c72d6ebf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_19_Pulumi.mp3", + "Episodes Pubdate Date": "2020-03-19", + "Episodes Summary": "

Infrastructure-as-code allows developers to use programming languages to define the architecture of their software deployments, including servers, load balancers, and databases. 

There have been several generations of infrastructure-as-code tools. Systems such as Chef, Puppet, Salt, and Ansible provided a domain-specific imperative scripting language that became popular along with the early growth of Amazon Web Services. Hashicorp’s Terraform project created an open source declarative model for infrastructure. Kubernetes YAML definitions are also a declarative system for infrastructure as code.

Pulumi is a company that offers a newer system for infrastructure as code, combining declarative and imperative syntax. Pulumi programs can be written in TypeScript, Python, Go, or .NET. Joe Duffy is the CEO of Pulumi, and he joins the show to talk about his work on the Pulumi project and his vision for the company. Joe also discusses his twelve years at Microsoft, and how his work in programming language tooling shaped how he thinks about building infrastructure-as-code.

", + "Episodes Title": "Pulumi: Infrastructure as Code with Joe Duffy", + "Episodes Uid": "SED3198893420", + "Episodes Audio File": "c0c0c59c2a671e9f6a0e5e885cf5488a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1tb", + "Episodes ID": "1fb9d274-e329-11ea-91a2-cbcd563a86b5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Openstack_Edited.mp3", + "Episodes Pubdate Date": "2016-03-29", + "Episodes Summary": "

Cloud service providers like Amazon, Google, and Microsoft provide both infrastructure as a service and platform as a service. Infrastructure as a service gives developers access to virtual machines, servers, and network infrastructure. Platform as a service is the software that runs on top of that infrastructure as a service–this includes things like Amazon DynamoDB, Microsoft Azure Machine Learning, and Google App Engine.

OpenStack is an open-source cloud operating system. Today’s guest is John Purrier, a founder of OpenStack and the CTO of Automic Software.

", + "Episodes Title": "OpenStack and the Future of Cloud Computing with John Purrier", + "Episodes Uid": "SED5948567270", + "Episodes Audio File": "f4685d3abca329ee6677c5be1f84e9df.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "016341f2-e978-11ea-ac22-7f5e83304f6d", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-08-31", + "Episodes Summary": "


", + "Episodes Title": "Noteable: Jupyter Notebook Platform with Matt Seal", + "Episodes Uid": "SED1541180333", + "Episodes Audio File": "c7c9637598314123261976263eccca22.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7iu", + "Episodes ID": "e83440a0-e328-11ea-91a2-1b75cd5fe1b2", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_20_ParlAI.mp3", + "Episodes Pubdate Date": "2020-08-20", + "Episodes Summary": "

Chatbots are useful for developing well-defined applications such as first-contact customer support, sales, and troubleshooting. But the potential for chatbots is so much greater. Over the last five years, there have been numerous platforms that have arisen to allow for better, more streamlined chatbot creation.

Dialogue software enables the creation of sophisticated chatbots. ParlAI is a dialogue platform built inside of Facebook. It allows for the development of dialogue models within Facebook. These chatbots can “remember” information from session to session, and continually learn from user input.

Stephen Roller is an engineer who helped build ParlAI, and he joins the show to discuss the history of chatbot applications and what the Facebook team is trying to accomplish with the development of ParlAI.

", + "Episodes Title": "ParlAI: Facebook Dialogue Platform with Stephen Roller", + "Episodes Uid": "SED7961128683", + "Episodes Audio File": "a5fab0dea00ad43fd978f8c856787d58.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "26o", + "Episodes ID": "14485f1e-e329-11ea-91a2-6f9b76abacc9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Slack_Security_edited.mp3", + "Episodes Pubdate Date": "2016-09-23", + "Episodes Summary": "

Security for the popular chat application Slack is a major focus for the company. A corporate Slack account is as valuable to a hacker as a corporate email account. In today’s episode, Ryan Huber and I talk through Slack’s approach to security–from philosophical discussions of how to company approaches security to the technical practices of logging and monitoring, and why Slack has a separate Amazon Web Services account just for the security team.
\nRyan works on security at Slack and has written a Medium post called Distributed Security Alerting, that I recommend checking out. If you haven’t heard it, you might also like the previous episode we did about Slack’s Architecture, with Keith Adams from Slack.

", + "Episodes Title": "Slack Security with Ryan Huber", + "Episodes Uid": "SED3368950597", + "Episodes Audio File": "f472d8c5d0ab99f6979654151dcc0007.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7cx", + "Episodes ID": "e8bf14f0-e328-11ea-91a2-7b09630b256a", + "Episodes Original URL": "https://sd-profile-pictures.s3-us-west-2.amazonaws.com/adfree/ReactNativeNader_adfree.mp3", + "Episodes Pubdate Date": "2020-06-26", + "Episodes Summary": "

Originally published July 6, 2017. We are taking a few weeks off. We’ll be back soon with new episodes.

React Native allows developers to reuse components from one user interface on multiple platforms. React Native was introduced by Facebook to reduce the pain of teams who were rewriting their user interfaces for web, iOS, and Android.

Nader Dabit hosts React Native Radio, a podcast about React Native. Nader also trains companies to use React Native through his company React Native Training. In this episode, we explore what a developer can and cannot do with React Native, when a developer needs to use native APIs, and some speculation on the future of React Native.

", + "Episodes Title": "React Native Ecosystem with Nader Dabit (Summer Break Repeat)", + "Episodes Uid": "SED3267181988", + "Episodes Audio File": "a0c7e8f704bbce5ab8d7c671e63b1dc2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1z2", + "Episodes ID": "1c6dc878-e329-11ea-91a2-f33b117b3ba3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Keen_Edited_3.mp3", + "Episodes Pubdate Date": "2016-05-24", + "Episodes Summary": "

The process of building a software project requires us to make so many architectural decisions. Which programming languages should be used? Which cloud service provider? Which database? A newer type of building block is the analytics platform. Companies need to track events, aggregate metrics, and change the user’s experience based on aggregated data.

Dan Kador is a co-founder of Keen IO, and he joins us to discuss the rise of analytics platforms. Keen’s architecture is based on Storm, Cassandra, and Kafka, and Keen uses these different building blocks to create a scalable, reliable analytics backend. On today’s episode, we explore the usage of analytics, the architecture of Keen’s backend system, and the business model of an analytics as a service company.

", + "Episodes Title": "Kafka, Storm, and Cassandra: Keen IO’s Analytics Architecture with Dan Kador", + "Episodes Uid": "SED7915084234", + "Episodes Audio File": "d9a5ffc36729fc20a6ff50893cd1291e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6vm", + "Episodes ID": "ea5ee344-e328-11ea-91a2-2b358318d933", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_27_BenTossellMakerpad.mp3", + "Episodes Pubdate Date": "2020-02-27", + "Episodes Summary": "

Low code tools can be used to build an increasing number of applications. Knowledge workers within a large corporation can use low code tools to augment their usage of spreadsheets. Entrepreneurs can use low code tools to start businesses even without knowing how to code.

Modern low code tools have benefited from steady improvements in cloud infrastructure, front-end frameworks like ReactJS, and browser technology such as the V8 JavaScript engine. These building blocks led to the popular low code products such as Webflow, Bubble, Retool, and Airtable. The low code products are supported by a broad selection of domain-specific APIs such as Stripe, Twilio, and Zapier.

Ben Tossell runs Makerpad, a site devoted to low-code and no-code applications. Makerpad describes how to use these tools to design sophisticated applications that don’t require you to write code. But they do require a different kind of software engineering. To create applications intelligently with low-code tools, you need to know how the tools fit together, and you need to be willing to persist through a process of iteration and debugging that is similar to traditional software engineering.

Ben joins the show to talk about his experience building low-code tools, the use cases for these tools, and his predictions for how they will impact the future of software.

", + "Episodes Title": "Makerpad: Low Code Tools with Ben Tossell", + "Episodes Uid": "SED4732855395", + "Episodes Audio File": "0b3dd799192120a00cfdbfd3a4b36a55.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "27d", + "Episodes ID": "13c035bc-e329-11ea-91a2-374967b47345", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ZuckerbergFiles_edited.mp3", + "Episodes Pubdate Date": "2016-09-28", + "Episodes Summary": "

Mark Zuckerberg may be the most powerful person in the world. At no other time in history has a single human had such fine-grained control over the most influential tool for media. Today’s guests are Michael Zimmer and Nick Proferes, the creators of The Zuckerberg Files, an index of every recorded word that Mark Zuckerberg has said in text, video, or audio.


\nWhy would someone create this? I was partly expecting Michael and Nick to be anti-Facebook, because The Zuckerberg Files sounds like a tool to hold the Facebook CEO accountable. In reality, Michael and Nick have a nuanced view of Facebook and Zuckerberg–they are Facebook users themselves, and they initially built The Zuckerberg Files as a way to portent product directions that Facebook might lean towards–particularly those related to privacy.

", + "Episodes Title": "Zuckerberg Files with Michael Zimmer and Nick Proferes", + "Episodes Uid": "SED3771149135", + "Episodes Audio File": "88d0ac32bf3eb14b77deab0e4e745ff0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23n", + "Episodes ID": "190a87f2-e329-11ea-91a2-83628e8281d8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/rancherlabs_Edited.mp3", + "Episodes Pubdate Date": "2016-07-20", + "Episodes Summary": "

Container management systems like Kubernetes and Docker Swarm give us a higher level management tool for architectures built out of distributed containers.

Container platforms like Rancher provide a higher layer of usability, and today’s guest Darren Shepherd of Rancher Labs takes us through what a container platform is. This interview is part of our continued coverage of Kubernetes, Docker, and the other components of the growing container ecosystem.

", + "Episodes Title": "Container Platforms with Darren Shepherd", + "Episodes Uid": "SED9329965690", + "Episodes Audio File": "370251e5f8ec02e6e3a3cc4d5176994f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "69u", + "Episodes ID": "ec20d836-e328-11ea-91a2-1b5b61f5f3f6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_04_IndieHackers2.mp3", + "Episodes Pubdate Date": "2019-10-04", + "Episodes Summary": "

Indie Hackers is a platform for independent software businesses to discuss strategy and find inspiration. Courtland Allen founded Indie Hackers with the goal of sharing the stories of these businesses, and the company has become a thriving community of entrepreneurs, engineers, and creators.

Business is a creative medium. The definition of a successful business is as subjective as the rules for what makes a successful work of art. A business owner can be miserable running a company that generates millions of dollars a year, and a new entrepreneur can feel ecstatic from making their first $5 sale.

Indie Hackers is a platform that is impossible to define in relation to things you have seen before. It is a media company with a podcast that most SE Daily listeners will probably enjoy. It is a social platform for learning how modern software companies are built. And it is a place where makers post their own progress on their creative projects (I have posted mine here).

Courtland was on the show three years ago to discuss the Indie Hackers movement in its nascent stages. Courtland returns to the show to discuss the thriving platform as it exists today, and a wide ranging conversation about software, game theory, and podcasting.

", + "Episodes Title": "Indie Hackers (3 Years Later) with Courtland Allen", + "Episodes Uid": "SED1834251430", + "Episodes Audio File": "8f988232cb7593f6549f3c068c0d4b5f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7dv", + "Episodes ID": "e8a2cbce-e328-11ea-91a2-931fa17edddd", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_06_FeaturePeek.mp3", + "Episodes Pubdate Date": "2020-07-06", + "Episodes Summary": "

The modern release workflow involves multiple stakeholders: engineers, management, designers, and product managers. It is a collaborative process that is often held together with brittle workflows. A developer deploys a new build to an ad hoc staging environment and pastes a link to that environment in Slack. Other stakeholders click on that link, then send messages to each other in Slack, or make comments on the pull request in GitHub.

This workflow is far from ideal. Collaborating around pull requests can be made easier with a dedicated set of tools for sharing and discussing those pull requests. This is the goal of FeaturePeek, a system for spinning up dedicated pull request environments, creating screenshots and comments, and reimagining the lifecycle of the release workflow.

Eric Silverman is a co-founder of FeaturePeek and he joins the show to discuss release management, the interactions between different stakeholders, and the development of his company. Much like the previous show about Postman, in which we explored how API management has become a ripe space for collaboration, the same is true of pull requests.

", + "Episodes Title": "Pull Request Environments with Eric Silverman", + "Episodes Uid": "SED3497270008", + "Episodes Audio File": "a34fd8adea90ec96728a8ab15aa7e588.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xk", + "Episodes ID": "ed1c0846-e328-11ea-91a2-5b1c5d2f80f5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_19_FacebookGraphQL.mp3", + "Episodes Pubdate Date": "2019-07-19", + "Episodes Summary": "

In 2011, Facebook had begun to focus its efforts on mobile development. Mobile phones did not have access to reliable, high bandwidth connections, and the Facebook engineering team needed to find a solution to improve the request latency between mobile clients and the backend Facebook infrastructure.

One source of latency was recursive data fetching. If a mobile application client made a request to the backend for newsfeed, the backend API would return the newsfeed, but some components of that feed would require additional requests to the backend. In practice, this might result in a newsfeed loading partially on a phone, but having a delayed loading time for the comments of a newsfeed item.

GraphQL is a solution that came out of this problem of recursive data fetching. A GraphQL server provides middleware to aggregate all of the necessary information to serve a complete request. GraphQL connects to backend data sources and federates the frontend request across these different data sources.

GraphQL was open sourced in 2015, and has found many use cases in addition to simplifying backend data fetching for mobile clients. Today, GraphQL is used by PayPal, Shopify, Twitter, and hundreds of other companies.

Lee Byron is the co-creator of GraphQL and he joins the show to tell the story of GraphQL, and how it fit into Facebook’s shift to mobile.

", + "Episodes Title": "Facebook GraphQL with Lee Byron", + "Episodes Uid": "SED3964229559", + "Episodes Audio File": "5693692d39fb1d460ba92c3f80217a14.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25w", + "Episodes ID": "15637dfc-e329-11ea-91a2-2f1b6d6fe62d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RelationalDBs.mp3", + "Episodes Pubdate Date": "2016-09-08", + "Episodes Summary": "

Relational databases are used by most applications. MySQL, Postgres, Microsoft SQL Server, and other products implement the core features of a relational database in different ways. A developer who has never studied this space in detail may not know the differences between these databases, and in this episode we describe some tradeoffs that relational databases can make.
\nCraig Kerstiens is an engineer at Citus Data, a company that makes scalable Postgres. We talk  about the requirements for a relational database, ACID compliance, how different databases handle different distributed systems problems, and the recent blog post from Uber about the company’s switch from Postgres to MySQL.

", + "Episodes Title": "Relational Databases with Craig Kerstiens", + "Episodes Uid": "SED4787890821", + "Episodes Audio File": "85449e4261a9032a5b5546e71e12118a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 196, + "Episodes ID": "2627cfee-e329-11ea-91a2-b78042840c1a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Soylent_Edited.mp3", + "Episodes Pubdate Date": "2016-01-08", + "Episodes Summary": "

Soylent is a meal replacement beverage, available in both liquid and powdered forms. Soylent is designed with the goal of meeting all nutritional requirements for an average adult.

John Coogan is the CTO of Soylent.

", + "Episodes Title": "Soylent Engineering with John Coogan", + "Episodes Uid": "SED4468758232", + "Episodes Audio File": "0b1ca27c06b1320e1f176d43bcc2c6ae.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6f2", + "Episodes ID": "eb99936c-e328-11ea-91a2-77ab9af23552", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_14_Quarkus.mp3", + "Episodes Pubdate Date": "2019-11-14", + "Episodes Summary": "

Java programs run in a different environment than they did ten years ago.

Modern infrastructure runs on containers sitting in a Kubernetes cluster. The optimal configuration for a Java program in that context is different than it was for an environment dominated by virtual machines and bare metal. When you are co-scheduling your services with each other, those services could be fighting for resources. You may want to optimize them with more ahead-of-time compilation.

Quarkus is a system for accelerating Java performance through the use of GraalVM. In a previous show, we explored the basics of GraalVM. In today’s show, Guillaume Smet and Emmanuel Bernard join the show to describe an application of GraalVM: the acceleration of Java. Guillaume and Emmaneul are engineers at Red Hat, and are working on changes to the Java ecosystem that are informed by the cloud and the rise of Kubernetes.

", + "Episodes Title": "GraalVM Quarkus: Java Acceleration with Guillaume Smet and Emmanuel Bernard", + "Episodes Uid": "SED5260441518", + "Episodes Audio File": "c774b0e03b090e9ece9e8202113b0538.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ha", + "Episodes ID": "2321d8ee-e329-11ea-91a2-179f206ffa35", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Npm_Edited.mp3", + "Episodes Pubdate Date": "2016-02-15", + "Episodes Summary": "

Node.js powers an increasing number of applications in the modern web. As node’s popularity grew, npm evolved in parallel as its default package manager and it has become a robust system for sharing and developing node programs. Yet today, npm is growing beyond its roots, and poised to become a generalized framework for all kinds of workflows within web development.

Laurie will be giving a talk at the 2016 O’Reilly Fluent Conference. If you want to win a free ticket to the conference, tweet about your favorite episode of Software Engineering Daily and tag @fluentconf and @software_daily.

Laurie Voss is the CTO of npm, Inc.

", + "Episodes Title": "npm with Laurie Voss", + "Episodes Uid": "SED2095115271", + "Episodes Audio File": "9923a7a08d4d48947d227016ea066f13.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "27i", + "Episodes ID": "139937dc-e329-11ea-91a2-f764bf9277df", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Andela_Edited_2.mp3", + "Episodes Pubdate Date": "2016-09-30", + "Episodes Summary": "

Africa has a huge reservoir of untapped technical talent. Tech companies have a huge amount of work they need skilled employees for. Andela recruits the most talented technologists across Africa, shapes them into world-class software developers, and places them with tech companies worldwide such as Google and Microsoft.

Brice Nkengsa is the director of engineering at Andela, and he joins the show to discuss Andela. This episode touches on many of the themes of Software Engineering Daily–boot camps, scaling an organization, microservices, and the future of work.

", + "Episodes Title": "Andela with Brice Nkengsa", + "Episodes Uid": "SED6167658003", + "Episodes Audio File": "6da343fcd1211775096d9acda82ce74a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1vn", + "Episodes ID": "1eb23934-e329-11ea-91a2-9fdcba60920e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Wiki_Edited.mp3", + "Episodes Pubdate Date": "2016-04-13", + "Episodes Summary": "

Wiki technology was invented decades ago to improve how software developers communicate. Today, Wikipedia has taken the ideas of the wiki to a new level, creating a free knowledge graph for the world to learn from.

Ward Cunningham developed WikiWikiWeb in 1994. He joins us today to discuss the first wiki, and how wikis have changed the way information propagates. Ward is not just an expert on how to write software–he is an expert on the software development experience, and we discuss how to build a community where software developers can overcome the fear of building something that has not been built before.

", + "Episodes Title": "Creating the Wiki with Ward Cunningham", + "Episodes Uid": "SED2118489006", + "Episodes Audio File": "aa34189af0ebfaf4f46682a8f6fd7967.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7gf", + "Episodes ID": "e86de8aa-e328-11ea-91a2-83c8050fefc0", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_21_SessionReplay.mp3", + "Episodes Pubdate Date": "2020-07-21", + "Episodes Summary": "

Users do not use web applications in the way that you might expect. And it is not easy to get the data that is necessary to get a full picture. But a newer API within browsers does make this more possible by capturing DOM mutations. 

The change capture of these DOM mutations can be stored for replay in the future. After being stored, this change capture can be retrieved and replayed. That allows for comprehensive frontend monitoring, which has been built into a product called FullStory.

Michael Morrissey is the CTO of FullStory, and he joins the show to talk about how session capture works, and the architecture of FullStory–how sessions get saved, stored and retrieved. In a previous show we talked about LogRocket, a product which does something similar.

", + "Episodes Title": "Session Replay with Michael Morrissey", + "Episodes Uid": "SED3084652436", + "Episodes Audio File": "793cd315c56f0b3e3ee5f2ef118a7426.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7hh", + "Episodes ID": "e85bad20-e328-11ea-91a2-1b0e5526aa75", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_27_AcquiredFM.mp3", + "Episodes Pubdate Date": "2020-07-27", + "Episodes Summary": "

Acquisitions are part of the technology industry. A successful corporation will often have an “exit”, either going public or becoming acquired. And with each of these corporations, there is a set of stories that narrate the company from beginning to end. 

Acquired is a podcast that tells the stories of companies such as YouTube, Instagram, and PayPal. During each episode, the life of a company is explored from its beginning til the end. Media companies, chip companies, and software companies all take the center stage on various episodes.

David Rosenthal and Ben Gilbert are the hosts of Acquired, and they join today’s show to talk about the podcast they started, a few business stories, and the podcast industry itself.

", + "Episodes Title": "Acquired Podcasting with David Rosenthal and Ben Gilbert", + "Episodes Uid": "SED8582611843", + "Episodes Audio File": "be9c9a12365fc32c74f079f51980abb6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1dq", + "Episodes ID": "24039cac-e329-11ea-91a2-5bb8f0a47492", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Soundcloud_Edited.mp3", + "Episodes Pubdate Date": "2016-02-04", + "Episodes Summary": "

Monoliths versus microservices – the architectural debate continues across the internet. SoundCloud is a popular music company that experienced the rapid development benefits of a monolith, as well as the long-term technical debt. That technical debt has since been relieved by a move towards microservices. In this episode of Software Engineering Daily, Lukasz joins Jeff to talk about the realities of moving from a monolith to a microservices architecture, and walks through the lessons learned at SoundCloud.

Lukasz Plotnicki is a consultant and software engineer at ThoughtWorks, which helps clients address their software development challenges and needs.

", + "Episodes Title": "Moving to Microservices at SoundCloud with Lukasz Plotnicki", + "Episodes Uid": "SED5033456960", + "Episodes Audio File": "622ae9435b069408b870306c1af0c92a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 754, + "Episodes ID": "e9951e1a-e328-11ea-91a2-63cf1dc7d39b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_28_CockroachDB.mp3", + "Episodes Pubdate Date": "2020-04-28", + "Episodes Summary": "

A relational database often holds critical operational data for a company, including user names and financial information. Since this data is so important, a relational database must be architected to avoid data loss.

Relational databases need to be a distributed system in order to provide the fault tolerance necessary for production use cases. If a database node goes down, the database must be able to recover smoothly without data loss, and this requires having all of the data in the database replicated beyond a single node.

If you write to a distributed transactional database, that write must propagate to each of the other nodes in the database. If you read from a distributed database, that read must return the same data that any other database reader would see. These constraints can be satisfied differently depending on the design of the database system. As a result, there is a vast market of distributed databases from cloud providers and software vendors.

CockroachDB is an open source, globally consistent relational database. CockroachDB is heavily informed by Google Spanner, the relational database that Google uses for much of its transactional workloads. Peter Mattis is a co-founder of CockroachDB, and he joins the show to discuss the architecture of CockroachDB, the process of building a business around a database, and his memories working on distributed systems at Google. Full disclosure: CockroachDB is a sponsor of Software Engineering Daily.

", + "Episodes Title": "CockroachDB with Peter Mattis", + "Episodes Uid": "SED7163783701", + "Episodes Audio File": "c45263e2d96001076cc1861394d2ed85.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1fm", + "Episodes ID": "235aeb16-e329-11ea-91a2-cf77a7c5be1c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Codecartoons_Edited_2.mp3", + "Episodes Pubdate Date": "2016-02-12", + "Episodes Summary": "

Lin Clark is today’s guest on Software Engineering Daily, and she joins Jeff to talk about Code Cartoons, a webcomic that explains Facebook’s open source projects like Flux and Relay with the same elegance and creativity as XKCD. Lin explains why cartoons can be a surprisingly effective way to introduce technologies to people without the fuss and intimidation of written tutorials or documentation.

At the 2016 O’Reilly Fluent Conference, Lin Clark will be speaking about Code Cartoons and the technologies that have sprung up around React JS. Software Engineering Daily is giving away a free ticket to the Fluent 2016 conference, which takes place on March 8-10 in San Francisco. If you want to be entered to win this free ticket, tweet about your favorite episode of Software Engineering Daily and tag @fluentconf and @software_daily.

Lin Clark is the creator of Code Cartoons, and a Senior Developer Tools Engineer at Mozilla.

", + "Episodes Title": "Code Cartoons with Lin Clark", + "Episodes Uid": "SED8390094021", + "Episodes Audio File": "7d2de95eeb7b1c719540b2404ec3de87.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6a8", + "Episodes ID": "ec1365de-e328-11ea-91a2-db9042673943", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_09_RyanCarson.mp3", + "Episodes Pubdate Date": "2019-10-09", + "Episodes Summary": "

The ability to create software is a superpower. But software education is not evenly distributed.

Ryan Carson started Treehouse to provide a high quality education system for anyone to learn how to build software. On a previous episode, Ryan and I discussed the field of programming education. Ryan returns to the show for a conversation about building Treehouse, and the company’s expansion from an online programming school to a platform for technology apprenticeship.

Thousands of people learn to program on Treehouse. Ryan’s goal is to connect those new programmers to companies where they can learn to apply those software skills to working at a technology company. Treehouse’s apprenticeship program is used by Airbnb, Adobe, Mailchimp, and others.

By combining an online education platform with an apprenticeship program, Treehouse has created a business model that could allow it to grow significantly bigger even in an atmosphere where learning to program has been commodified to a large extent. The economic model of Treehouse contrasts with in-person bootcamps such as Hack Reactor and online income sharing platforms such as Lambda School.

It was a great conversation about modern technology, the future of education, and the strategy of building a successful business.

", + "Episodes Title": "Treehouse: Business and Education with Ryan Carson", + "Episodes Uid": "SED1959632632", + "Episodes Audio File": "c406b8d23d14fe7c11e0875105874d99.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7hl", + "Episodes ID": "e847f604-e328-11ea-91a2-cbeacb340796", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_31_SecurityMonitoring.mp3", + "Episodes Pubdate Date": "2020-07-31", + "Episodes Summary": "

Logs are the source of truth. If a company is sufficiently instrumented, the logging data that streams off of the internal infrastructure can be refined to tell a comprehensive story for what is changing across that infrastructure in real time. This includes logins, permissions changes, other events that could signal a potential security compromise.

Datadog is a company that was built around log management, metrics storage, and distributed tracing. More recently, they have also built tools for monitoring the security of an organization. Detecting security threats can be achieved by alerting on known security risks, or pieces of information that could be indicative of a vulnerability.

Marc Tremsal works at Datadog, and joins the show to talk through security monitoring. Full disclosure: Datadog is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Security Monitoring with Marc Tremsal", + "Episodes Uid": "SED3926744230", + "Episodes Audio File": "209aabc6b250e0b4e06e6e85e820569e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ws", + "Episodes ID": "ea458bec-e328-11ea-91a2-c785963e9346", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_05_ReactStackTejasKumar.mp3", + "Episodes Pubdate Date": "2020-03-05", + "Episodes Summary": "

JavaScript fatigue. This phrase has been used to describe the confusion and exhaustion around the volume of different tools required to be productive as a JavaScript developer. Frameworks, package managers, typing systems, state management, GraphQL, and deployment systems–there are so many decisions to make.

In addition to the present-day tooling choices, a JavaScript developer needs to watch the emerging developments in the ecosystem. ReactJS is evolving at a rapid clip, and newer primitives such as React Hooks and React Suspense allow developers to handle concurrency and networking more robustly.

Tejas Kumar works with G2i, a company that connects React developers with organizations that are looking for high-quality engineers. His role at G2i is head of vetting, which requires him to assess engineers for their competency in JavaScript-related technologies. Tejas joins the show to discuss the modern stack of technologies that a React developer uses to build an application. Full disclosure: G2i, where Tejas works, is a sponsor of Software Engineering Daily.

Tejas is also speaking at Reactathon, a San Francisco JavaScript conference taking place March 30th and 31st in San Francisco. This week we will be interviewing speakers from Reactathon, and if you are interested in JavaScript and the React ecosystem then stay tuned, and if you hear something you like, you can check out the Reactathon conference in person.

", + "Episodes Title": "React Stack with Tejas Kumar", + "Episodes Uid": "SED8650134159", + "Episodes Audio File": "7477d1a5ed45b3b78fc21d4dcf695920.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1fd", + "Episodes ID": "2376cdfe-e329-11ea-91a2-0f5622aa7974", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Postbrowser_Edited_2.mp3", + "Episodes Pubdate Date": "2016-02-11", + "Episodes Summary": "

Prepare for the post-browser world, says today’s guest Jonathan Stark. We are moving beyond the browser, into a world where the web is consumed by a variety of front ends.

Jonathan is a speaker at the upcoming O’Reilly Fluent Conference in San Francisco, and you can win a free ticket to the conference. To be entered into a random drawing for that ticket, send us a tweet about your favorite episode of Software Engineering Daily between now and February 22nd. Include the hashtag #fluentconf and and tag us @software_daily to make sure we can see your tweet.

Fluent is a conference about the web platform–which certainly includes the browser, but also mobile apps, VR experiences, and smart objects connected to the web. In today’s episode, Jeff and Jonathan explore what adjustments developers should make in this post-browser world.

Jonathan Stark is a mobile consultant who helps consumer brands thrive in the post-PC era.

", + "Episodes Title": "Web Development in a Post-browser World with Jonathan Stark", + "Episodes Uid": "SED7220593963", + "Episodes Audio File": "1b5f3335409e954f4c2af74107790255.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1rp", + "Episodes ID": "201a6c9c-e329-11ea-91a2-db6cd4e6bba9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Mic_Edited_2.mp3", + "Episodes Pubdate Date": "2016-03-23", + "Episodes Summary": "

Mic.com is a media company focused on news for millennials. Anthony Sessa is the VP of product at Mic.com, and he joins us to talk about the engineering of a modern news organization tailored to young people. We discuss data engineering, frontend technologies, and how to migrate away from WordPress. We also explore how to build a successful media company today, and how millennials want to consume news and software.

", + "Episodes Title": "Building Software for Millenials with Anthony Sessa", + "Episodes Uid": "SED1474167343", + "Episodes Audio File": "6d9a999b877954a4eddeca314939f6fe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 239, + "Episodes ID": "1975d4a8-e329-11ea-91a2-9b06be496100", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Economics_Edited.mp3", + "Episodes Pubdate Date": "2016-07-15", + "Episodes Summary": "

EconTalk is a weekly economics podcast that has been going for a decade. On EconTalk, Russ Roberts brings on writers, intellectuals, and entrepreneurs for engaging conversations about the world as seen through the lens of economics.

Russ Roberts is today’s guest, and it is a treat because I have been listening to EconTalk since 2006 and it was a central point of inspiration for what Software Engineering Daily has become. On this episode, we talk about how software impacts the world economically, from bitcoin’s promise of zero cost transactions to the opportunities and regulatory challenges of the software-enabled gig economy.

", + "Episodes Title": "Economics of Software with Russ Roberts", + "Episodes Uid": "SED7866227577", + "Episodes Audio File": "403c45e7b54e46b92c9c35b555e0168c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1zv", + "Episodes ID": "1bf0c792-e329-11ea-91a2-03884ea92567", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/OpenShift_clayton_Edited.mp3", + "Episodes Pubdate Date": "2016-06-01", + "Episodes Summary": "

Kubernetes is the container management platform that came out of Google’s experiences managing data centers. Kubernetes abstracts away many of the frustrations of distributed systems management. OpenShift is a platform built on top of Kubernetes to provide an additional layer of usability.
\nClayton Coleman is the lead engineer of OpenShift, and in our conversation today, we start with the basics of Kubernetes, then talk about OpenShift–Clayton explains why we need another abstraction on top of Kubernetes. Near the end of the conversation, we discuss the current state of cloud products–which can be confusing. Mesosphere, Swarm, Kubernetes, OpenStack, ECS–why do we need all of these different products? Clayton gives his perspective, and explains why it is not going to get any less confusing any time soon.

", + "Episodes Title": "Kubernetes and OpenShift with Clayton Coleman", + "Episodes Uid": "SED4615941161", + "Episodes Audio File": "40ee70414ddf569e5e875a1f4bca7928.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "29j", + "Episodes ID": "11b5c37c-e329-11ea-91a2-ffd91293bb92", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ghostery_edited.mp3", + "Episodes Pubdate Date": "2016-11-03", + "Episodes Summary": "

When you visit a web page, that web page can write data to a file on your computer, known as a cookie. Scripts on that page can also read from your cookie file to understand where you have been in the past. All of this data about you is getting shared between advertising companies like Google, Facebook, and AppNexus.

Ghostery is a browser extension that allows you to limit what you share with these online tracking companies. Larry Furr develops products at Ghostery, and on this episode he takes us through the process of how we are tracked through the Internet.

We also explore the topic of ad fraud, which is a theme we will continue to explore on SE Daily. If you have any information on ad fraud, or have recommendations for guests, please email me at jeff@softwareengineeringdaily.com

", + "Episodes Title": "Ad Tracking with Larry Furr", + "Episodes Uid": "SED7374029090", + "Episodes Audio File": "a5441b691b1973545de12e7804d47a0b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7k7", + "Episodes ID": "105e6eca-e5f9-11ea-9e48-6f25fe03bcbd", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_24_Iterative.mp3", + "Episodes Pubdate Date": "2020-08-24", + "Episodes Summary": "

Code is version controlled through git, the version control system originally built to manage the Linux codebase. For decades, software has been developed using git for version control. More recently, data engineering has become an unavoidable facet of software development. It is reasonable to ask–why are we not version controlling our data?

Dmitry Petrov is the founder of Iterative.ai, a company for collaborating and version controlling data sets. Dmitry joins the show to talk about how data version control works, and Iterative.ai, the company he is building around dataset management and collaboration.

", + "Episodes Title": "Data Version Control with Dmitry Petrov", + "Episodes Uid": "SED4225417348", + "Episodes Audio File": "edf2df667e39d4ae0affb2bec87890da.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2a4", + "Episodes ID": "114f3e86-e329-11ea-91a2-c7b2147ebbd4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/infrastructuremistakes_edited.mp3", + "Episodes Pubdate Date": "2016-11-11", + "Episodes Summary": "

The blueprint for a typical startup involves investing heavily in cloud services–either from Amazon, Google, or Microsoft. The high costs can quickly eat away at all of the money that startup has raised. In today’s episode, Avi Freedman outlines some of the infrastructure mistakes that can set back a company severely–cloud jail, hipster tools, and lack of monitorability.

Avi is the CEO of Kentik, a network traffic, performance, and security visibility company, so he gets lots of perspective on the infrastructure of the average company. We also discussed the business of running a software company, contrasted with the life of a poker player. Avi and I both have some experience playing high stakes poker, so it was a great opportunity to get his perspective on the parallels between the two fields.

", + "Episodes Title": "Infrastructure Mistakes with Avi Freedman", + "Episodes Uid": "SED4393625981", + "Episodes Audio File": "1373aee8299006697a7c239d33f9f4fd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6i8", + "Episodes ID": "eb3b4a14-e328-11ea-91a2-1f81f5b697d2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_11_SumoLogicContinuousIntelligence.mp3", + "Episodes Pubdate Date": "2019-12-11", + "Episodes Summary": "

Logging provides raw data that can be abstracted into higher level information.

Logs are generated at every layer of infrastructure: physical host, virtual machine, container, pod, and Kubernetes cluster. Logs are generated by network proxies, edge servers, and API requests. There is far too much logging information to be read by humans. 

Log messages need to be refined into statistical metrics that can be put into charts. A high volume of log messages can be used to detect anomalies across a system. If unusual behavior is present in a system, the relevant log messages can be identified and sent to a human operator for them to triage and respond to.

Kalyan Ramanathan works at Sumo Logic, a platform for log management and continuous intelligence. Sumo Logic recently published the Continuous Intelligence Report, which is based on a study of over 2000 technology companies. This is a useful data set for anyone who is looking to understand adoption of cloud products and Kubernetes, and it can be found at softwareengineeringdaily.com/sumologic. Kalyan joins the show to discuss log management, continuous intelligence, and the data that Sumo Logic gathered in the Continuous Intelligence Report. Full disclosure: Sumo Logic is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Continuous Intelligence with Kalyan Ramanathan", + "Episodes Uid": "SED5818301043", + "Episodes Audio File": "021ba260419d8b2696ed2e5fac715617.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ih", + "Episodes ID": "eb1d72fa-e328-11ea-91a2-738c624c6826", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_19_SwyxLowCodeJAMStack.mp3", + "Episodes Pubdate Date": "2019-12-19", + "Episodes Summary": "

The software category known as “no-code” describes a set of tools that can be used to build software without writing large amounts of code in a programming language.

No-code tools use visual interfaces such as spreadsheets and web based drag-and-drop systems. In previous shows, we have covered some of the prominent no-code products such as Airtable, Webflow, and Bubble. It is clear that no-code tools can be used to build core software infrastructure in a manner that is more abstract than the typical software engineering model of writing code.

No-code tools do not solve everything. You can’t use a no-code tool to build a high performance distributed database, or a real-time multiplayer video game. But they are certainly useful for building internal tools and basic CRUD applications.

We know that no-code tools can create value. But how do they fit into the overall workflow of a software company? How should teams be arranged now that knowledge workers can build certain kinds of software without writing code? And how should no-code systems interface with the monoliths, microservices, and APIs that we have building for years?

Shawn Wang is an engineer with Netlify, a cloud provider that is focused on delivering high-quality development and deployment experience. Netlify is not a no-code platform, but Shawn has explored and written about the potential of no-code systems. Since he comes from a code-heavy background, he is well-positioned to give a realistic perspective on how no-code systems might evolve to play a role in the typical software development lifecycle.

", + "Episodes Title": "No Code with Shawn Wang", + "Episodes Uid": "SED1552600781", + "Episodes Audio File": "4a6f160a48ef86e9ddca4fe37f2ac644.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ab", + "Episodes ID": "e918590c-e328-11ea-91a2-6786a951da49", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_01_DisaggregatedServers.mp3", + "Episodes Pubdate Date": "2020-06-01", + "Episodes Summary": "

Server infrastructure traditionally consists of monolithic servers containing all of the necessary hardware to run a computer. These different hardware components are located next to each other, and do not need to communicate over a network boundary to connect the CPU and memory.

LegoOS is a model for disaggregated, network-attached hardware. LegoOS disseminates the traditional operating system functionalities into loosely-coupled hardware and software components. By disaggregating data center infrastructure, the overall resource usage and failure rate of server infrastructure can be improved.

Yiying Zhang is an assistant professor of computer science at UCSD. Her research focuses on operating systems, distributed systems, and datacenter networking. She joins the show to discuss her work and its implications for data centers and infrastructure.

", + "Episodes Title": "Disaggregated Servers with Yiying Zhang", + "Episodes Uid": "SED2730357627", + "Episodes Audio File": "d4bde516e88f4824b12a60f55bed1c2f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ef", + "Episodes ID": "0ba316f6-e329-11ea-91a2-e3e87595d15a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/websecurity_edited.mp3", + "Episodes Pubdate Date": "2017-01-09", + "Episodes Summary": "

Vulnerabilities exist in every computer system. As a system gets bigger, the number of vulnerabilities magnifies. The web is the biggest, most complex computer system we have–but fortunately, the steps we can take to secure our web applications are often quite simple.

Jared Smith is a cyber security research scientist with Oak Ridge National Laboratory. He joined me on the show to discuss web application security, but I really wanted to know his position on some of the more grandiose topics–Stuxnet, our power grid, Russian hacking, and corporate backdoors.

This was a wide ranging discussion and I enjoyed it a lot. For a presentation Jared gave at Nodevember about Web Security, check out this YouTube video.

", + "Episodes Title": "Cyber Warfare with Jared Smith", + "Episodes Uid": "SED7376455523", + "Episodes Audio File": "813735a6e99113357d60331823d318b8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "20l", + "Episodes ID": "1ae2268e-e329-11ea-91a2-37c73f61eb11", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Vault_Edited.mp3", + "Episodes Pubdate Date": "2016-06-16", + "Episodes Summary": "

Every software application has secrets. User passwords and database credentials must be managed carefully, because poor access controls can lead to disaster scenarios. Vault is a tool for secret management, developed at Hashicorp, a company that builds software tools for application delivery and infrastructure management.

Seth Vargo is a software engineer and open source advocate at Hashicorp, and in today’s episode he discusses the advantages of having a single tool to manage all of your secrets. If you aren’t a security expert, don’t worry, we discuss some of the basics of security. And if you are a security expert, you will appreciate the comparisons we discuss between Hashicorp and other tools that have been used for secret management.

", + "Episodes Title": "Secret Management and Vault with Hashicorp’s Seth Vargo", + "Episodes Uid": "SED6539711469", + "Episodes Audio File": "57869e4a06586f3d2b7f3eb7e1e266be.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1w8", + "Episodes ID": "1e08d6d2-e329-11ea-91a2-bf7208f65133", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Graphingfacebook_Edited_2.mp3", + "Episodes Pubdate Date": "2016-04-22", + "Episodes Summary": "

Graphing when your Facebook Friends are awake” was trending at the top of Hacker News when Alex Hogue first posted it. Alex wrote a blog post about this piece of software he built that interacts with public Facebook APIs to detect when any of his friends are awake or asleep.
\nAs I read that post, I wanted to talk to Alex, because it was such a creative and technical piece of software–but it is surprising that someone would take the time to randomly inspect the elements of the Facebook page, reverse engineer the way Facebook sends data about statuses, mine data from that reverse engineering, and create a bunch of graphs about that data.

Today, Alex joins me to explain how and why he built a tool to graph when people are awake or asleep using Facebook data.

", + "Episodes Title": "Reverse Engineering Facebook with Alex Hogue", + "Episodes Uid": "SED8957214209", + "Episodes Audio File": "ddc569d5408658fdb005d67af513953c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "78p", + "Episodes ID": "e93495ea-e328-11ea-91a2-239ce3d9ce07", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_22_Redwood.mp3", + "Episodes Pubdate Date": "2020-05-22", + "Episodes Summary": "

Over the last 5 years, web development has matured considerably. React has become a standard for frontend component development. GraphQL has seen massive growth in adoption as a data fetching middleware layer. The hosting platforms have expanded beyond AWS and Heroku, to newer environments like Netlify and Vercel.

These changes are collectively known as the JAMStack. With the changes brought by the JAMStack, it raises the question: how should an app be built today? Can a framework offer guidance for how the different layers of a JAMStack app should fit together?

RedwoodJS is a framework for building JAMStack applications. Tom Preston-Werner is one of the creators of RedwoodJS, as well as the founder of GitHub and Chatterbug, a language learning app. He joins the show to talk about the future of JAMStack development, and his goals for RedwoodJS.

", + "Episodes Title": "RedwoodJS with Tom Preston-Werner", + "Episodes Uid": "SED1857366533", + "Episodes Audio File": "60815106b6ef607b50ad4cbd253e6c17.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6l7", + "Episodes ID": "eb01093a-e328-11ea-91a2-67f590d970eb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_10_JoshWillsSlackSearch.mp3", + "Episodes Pubdate Date": "2020-01-10", + "Episodes Summary": "

Slack is a messaging platform for organizations. Since its creation in 2013, Slack has quickly become a core piece of technology used by a wide variety of technology companies, groups, and small teams. 

The messages that are sent on Slack are generated at a very high volume, and are extremely sensitive. These messages must be stored on Slack’s servers in a way that does not risk a message from one company accidentally being accessible to another company. The messages must be highly available, and they also must be indexed for search.

When Slack was scaling, the company started to encounter limitations in its data infrastructure that the company was unsure how to solve. During this time, Josh Wills was the director of data engineering at Slack, and he joins the show to retell the history of his time at Slack, and why the problem of searching messages was so hard. 

Josh also provides a great deal of industry context around how engineers from Facebook and Google differ from one another. When Slack was starting to become popular, the company quickly began to attract engineers from both of those companies. Facebook and Google have distinct solutions for how they have tackled the problems of data engineering.

", + "Episodes Title": "Slack Data Platform with Josh Wills", + "Episodes Uid": "SED2401359031", + "Episodes Audio File": "9502d201367d80fc5bc942707b98e482.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ie", + "Episodes ID": "eb26ef9c-e328-11ea-91a2-3364a9ba38a5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_17_CruisePlatformEng.mp3", + "Episodes Pubdate Date": "2019-12-17", + "Episodes Summary": "

Cruise is a company that is building a fully automated self-driving car service.

The infrastructure of a self-driving car platform presents a large number of new engineering problems. Self-driving cars collect vast quantities of data as they are driving around the city. This data needs to be transferred from the cars onto cloud servers. The data needs to be used for training machine learning models. These models must be tested in a simulated environment, which provides more data to be integrated back into the self-driving system that is deployed to the cars.

As the cars drive around the city, they can communicate with custom cloud services to get information about traffic, navigation, and weather. Cloud services are also used for internal tooling that can help with automotive diagnostics, configuration changes, deployments, and security policy management.

The software platform used to manage infrastructure at Cruise is a combination of cloud products, open source tools, and custom built infrastructure that is mostly deployed to Kubernetes. Karl Isenberg is an engineer at Cruise, and he joins the show to talk about the engineering requirements of building a self-driving car service, and Cruise’s approach to platform engineering.

", + "Episodes Title": "Kubernetes at Cruise with Karl Isenberg", + "Episodes Uid": "SED3569823273", + "Episodes Audio File": "6971dd02eb5de2ef4a191d979234df17.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 256, + "Episodes ID": "1675738a-e329-11ea-91a2-374bfcc47157", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ServerlessArticle_Edited.mp3", + "Episodes Pubdate Date": "2016-08-23", + "Episodes Summary": "

“Serverless” usually refers to an architectural pattern where the server side logic is run in stateless compute containers that are event-triggered and ephemeral. Mike Roberts has written a series of articles about serverless computing, in which he discusses theories and patterns around serverless architecture.
\nIn this episode, Mike and I discuss how to reimagine our software architecture using functions-as-a-service. We go into the costs, benefits, and modern limitations of current serverless platforms like AWS Lambda.

", + "Episodes Title": "Serverless Architecture with Mike Roberts", + "Episodes Uid": "SED4191827531", + "Episodes Audio File": "b34c70f0a48506930ccac1eff2c14c86.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 201, + "Episodes ID": "1bb9b7e8-e329-11ea-91a2-0b43fd043091", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Polymer_Edited.mp3", + "Episodes Pubdate Date": "2016-06-06", + "Episodes Summary": "

Smart phone apps have better performance than web apps. When we have an application that we use on a regular basis, we download that application to a smart phone rather than using the browser based version on our mobile browser. Google’s Polymer Project wants to improve the gap between native app performance and mobile web app performance. The key problem with mobile web is that we are sending huge JavaScript bundles to mobile devices, which inhibits performance. The Polymer Project is working to build more functionality into our mobile browsers so that it is easier to load these heavy web applications.


\nRob Dodson is a developer advocate with Google. Today’s episode explores the past, present, and future of web application development, from jQuery to React to progressive web apps. The Polymer project also represents a push towards better support for people in developing countries, where internet connections are less reliable. Sponsors

", + "Episodes Title": "Google’s Polymer Project with Rob Dodson", + "Episodes Uid": "SED3669972559", + "Episodes Audio File": "0e1d7813714e36c604572a76bfc9ba43.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "72y", + "Episodes ID": "e9c455b8-e328-11ea-91a2-277db762d60f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_14_CephStorage.mp3", + "Episodes Pubdate Date": "2020-04-14", + "Episodes Summary": "

Ceph is a storage system that can be used for provisioning object storage, block storage, and file storage. These storage primitives can be used as the underlying medium for databases, queueing systems, and bucket storage. Ceph is used in circumstances where the developer may not want to use public cloud resources like Amazon S3.

As an example, consider telecom infrastructure. Telecom companies that have their own data centers need software layers which make it simpler for the operators and developers that are working with that infrastructure to spin up databases and other abstractions with the same easy experience that is provided by a cloud provider by AWS.

Sage Weil has been a core developer on Ceph since 2005, and the company he started around Ceph sold to Red Hat for $175 million. Sage joins the show to talk about the engineering behind Ceph and his time spent developing companies.

", + "Episodes Title": "Ceph Storage System with Sage Weil", + "Episodes Uid": "SED2804262157", + "Episodes Audio File": "c15a39188a10b73e3898618bd203ac93.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6zp", + "Episodes ID": "ea04b95a-e328-11ea-91a2-fb74ed43c796", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_25_Sorbet.mp3", + "Episodes Pubdate Date": "2020-03-25", + "Episodes Summary": "

Programming languages are dynamically typed or statically typed. In a dynamically typed language, the programmer does not need to declare if a variable is an integer, string, or other type. In a statically typed language, the developer must declare the type of the variable upfront, so that the compiler can take advantage of that information.

Dynamically typed languages give a programmer flexibility and fast iteration speed. But they also introduce the possibility of errors that can be avoided by performing type checking. This is one of the reasons why TypeScript has risen in popularity, giving developers the option to add types to their JavaScript variables.

Sorbet is a typechecker for Ruby. Sorbet allows for gradual typing of Ruby programs, which helps engineers avoid errors that might otherwise be caused by the dynamic type system. Dmitry Petrashko is an engineer at Stripe who helped build Sorbet. He has significant experience in compilers, having worked on Scala before his time at Stripe. Dmitry joins the show to discuss his work on Sorbet, and the motivation for adding type checking to Ruby.

We’re looking for new show ideas, so if you have any interesting topics, please feel free to reach out via twitter or email us at  jeff@softwareengineeringdaily.com

We realize right now humanity is going through a hard time with the Caronovirus pandemic, but we all have skills useful to fight this battle. Head over to codevid19.com to join the world’s largest pandemic hackathon!

", + "Episodes Title": "Sorbet: Typed Ruby with Dmitry Petrashko", + "Episodes Uid": "SED2527659518", + "Episodes Audio File": "788e44ccdd97582ed0f91fd579c119a5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1zo", + "Episodes ID": "1c1b6f06-e329-11ea-91a2-c354e7f9f82d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Saltstack_Edited.mp3", + "Episodes Pubdate Date": "2016-05-30", + "Episodes Summary": "

Infrastructure-as-code is a trend that has been popularized over the past decade, as cloud computing and distributed systems have become a part of every technology company. Tools like Salt, Puppet, Chef, and Ansible allow us to manage servers and processes from the command line.
\nDavid Boucha works at SaltStack, the company that makes Salt. Salt is a platform that provides configuration management and remote execution.

In our conversation today, we discuss how the distributed systems architecture of Salt works, and how it can be used in practice. We also discuss infrastructure-as-code in the context of modern infrastructure tools like containers and Kubernetes.

", + "Episodes Title": "Infrastructure as Code with SaltStack’s David Boucha", + "Episodes Uid": "SED1326387908", + "Episodes Audio File": "876493e45ba6baf61976233417c1fd5c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 166, + "Episodes ID": "27564d50-e329-11ea-91a2-6be215ca1bb6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Quora_Edited.mp3", + "Episodes Pubdate Date": "2015-12-28", + "Episodes Summary": "

Quora is a Q&A website where questions are asked, answered, edited and organized by its community of users.

Shreyes Seshasai is the Director of Engineering at Quora.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Engineering at Quora with Shreyes Seshasai", + "Episodes Uid": "SED6864614494", + "Episodes Audio File": "6d74cbfd7775beb14f323d3d4aac8a44.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1t3", + "Episodes ID": "1fc63cbc-e329-11ea-91a2-ef00d4527044", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Ride_Edited.mp3", + "Episodes Pubdate Date": "2016-03-28", + "Episodes Summary": "

In today’s episode, Ben Halpern interviews Juan Buritica, VP of Engineering at Ride. They discuss Ride’s migration from a monolith to microservices, the challenges of running a distributed team and preventing developer burnout.

", + "Episodes Title": "Microservices, Distributed Teams, and Conferences with Juan Pablo Buriticá", + "Episodes Uid": "SED2637520917", + "Episodes Audio File": "3dd120da24dd015a89e5e54f23aeaa28.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 766, + "Episodes ID": "e962a318-e328-11ea-91a2-6bf11154b938", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_05_10_SocialDistancingData.mp3", + "Episodes Pubdate Date": "2020-05-11", + "Episodes Summary": "

Social distancing has been imposed across the United States. We are running an experiment unlike anything before it in history, and it is likely to have a lasting impact on human behavior. By looking at location data of how people are moving around today, we can examine the real-world impacts of social distancing.

SafeGraph is a company that provides geospatial location data to be used by developers and researchers. Much of their data is aggregated from cell phone GPS pings which identify where anonymized users are in the world. This data set provides the basis for SafeGraph’s social distancing metrics, which measure how frequently people are coming into contact with one another.

Ryan Fox Squire works at SafeGraph, and he returns to the show to discuss social distancing metrics and the research that has come out of studying these metrics.

", + "Episodes Title": "Social Distancing Data with Ryan Fox Squire", + "Episodes Uid": "SED4941286666", + "Episodes Audio File": "1cc1e1c351bff075e4702eacad780b60.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 765, + "Episodes ID": "e9756322-e328-11ea-91a2-3bf79a79cd4c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_05_05_MulticloudMySQL.mp3", + "Episodes Pubdate Date": "2020-05-05", + "Episodes Summary": "

For many applications, a transactional MySQL database is the source of truth. To make a MySQL database scale, some developers deploy their database using Vitess, a sharding system built on top of Kubernetes. 

Jiten Vaidya and Anthony Yeh work at PlanetScale, a company that focuses on building and supporting MySQL databases sharded with Vitess. Their experience comes from working at YouTube, which has a massive, rapidly growing database for storing the information about videos on the site. Sharding is not the only database problem that YouTube faced. Availability was another issue.

At YouTube, the database operators want YouTube’s MySQL cluster to be resilient to the failure of an entire data center. Similarly, a developer deploying an important MySQL database to the cloud wants their database to be resilient to the failure of an entire cloud provider. Jiten and Anthony join the show to talk about their work building multicloud support for MySQL, and their process of deploying a consistent MySQL database in Azure, GCP, and AWS.

", + "Episodes Title": "Multicloud MySQL with Jiten Vaidya and Anthony Yeh", + "Episodes Uid": "SED9670451315", + "Episodes Audio File": "0189370b4770bf5ed6bafd69e3b826fd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1i2", + "Episodes ID": "22fe1e90-e329-11ea-91a2-7b76f7d11d13", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Accessibility_Edited.mp3", + "Episodes Pubdate Date": "2016-02-17", + "Episodes Summary": "

Disabled individuals account for over a billion people worldwide. This represents the world’s largest minority on the Web, with $220 billion in discretionary spending power in the United States alone. Yet, the accessible web is more than a financial issue – it is also a moral issue, and it is crucial that we make the web accessible to ensure an equitable information platform.

Today’s guest Nic Steenhout joins us to explain how to develop software with accessibility in mind. At the upcoming Fluent Conference, he will be giving a talk entitled Don’t turn off that JavaScript just yet, referencing JavaScript’s history of causing accessibility problems. If you want to win a free ticket to Fluent, tweet about your favorite episode of Software Engineering Daily and tag @fluentconf and @software_daily.

Nic Steenhout is a software engineer and an accessibility consultant at Simply Accessible.

", + "Episodes Title": "Web Accessibility with Nic Steenhout", + "Episodes Uid": "SED2095189330", + "Episodes Audio File": "8e5bf3a3ca290bd05abff70d1cf58e58.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "29n", + "Episodes ID": "11954368-e329-11ea-91a2-4bd230bd1fde", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/legacycode_edited.mp3", + "Episodes Pubdate Date": "2016-11-07", + "Episodes Summary": "

Legacy code is code without automated tests. Most companies have lots of legacy code, and most developers don’t like working on legacy code. Why is that? What is it that makes legacy code so difficult to work with? And why does a large amount of legacy code slow down an organization so severely?

Andrea Goulet is the CEO of Corgibytes, a consultancy that specializes in remodeling legacy codebases. Andrea’s company developed out of an observation that there are developers who actually love working on legacy code. Since founding Corgibytes, she has become an expert on legacy code and published a recent article about Building Technical Wealth. The article presents ways that companies can confront the realities of legacy code.

", + "Episodes Title": "Legacy Code with Andrea Goulet", + "Episodes Uid": "SED6671883071", + "Episodes Audio File": "70a975f613d2d28f6f75d4280584d054.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25e", + "Episodes ID": "15e42c40-e329-11ea-91a2-a341e97564ab", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/AI_Research_Edited_2.mp3", + "Episodes Pubdate Date": "2016-08-29", + "Episodes Summary": "

Research in artificial intelligence takes place mostly at universities and large corporations, but both of these types of institutions have constraints that cause the research to proceed a certain way. In a university, basic research might be hindered by lack of funding. At a big corporation, the researcher might be encouraged to study a domain that is not squarely in the interest of public good–such as targeted advertising.

Oren Etzioni is the CEO of the Allen Institute for Artificial Intelligence, and in this episode we discuss AI research–from the doomful premonitions of Nick Bostrom to the unbridled optimism of Ray Kurzweil, as well as the realities of how AI research actually proceeds. Projects at the Allen Institute are defined and structured to solve problems in an intelligent, scalable fashion, so that engineering can proceed steadily from the local maxima of a problem domain to the global maxima. The Allen Institute seeks to bridge the gap by providing ample funding for open source AI research for the common good.

Oren is also speaking at the O’Reilly Artificial Intelligence Conference in New York, September 26-27.

", + "Episodes Title": "Artificial Intelligence with Oren Etzioni", + "Episodes Uid": "SED1256051570", + "Episodes Audio File": "0a2836593598351438f38854a62665a9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "19w", + "Episodes ID": "25ef707c-e329-11ea-91a2-73d69d8ca44f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Rails_2.mp3", + "Episodes Pubdate Date": "2016-01-13", + "Episodes Summary": "

Ruby on Rails is a web app framework released 10 years ago that influenced the way websites were being built. Rails skyrocketed to popularity in the late 2000’s and empowered many small companies to quickly build and maintain robust web apps.

While it is still a mainstay in web development, it has been overshadowed as of late by JavaScript, and Node.js on the backend. David joins Software Engineering Daily to discuss how Ruby on Rails has evolved to keep up with newer programming paradigms and why it is still an excellent choice to build web apps with nowadays.

David Heinemeier Hansson is the creator of Ruby on Rails and a partner at Basecamp. Rails was extracted from the work done at Basecamp, and open-sourced for the public to commit to and use for their applications.

", + "Episodes Title": "The Evolution of Rails with David Heinemeier Hansson", + "Episodes Uid": "SED1037369927", + "Episodes Audio File": "78f97a05cb8218a044f203ceb3062645.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "x8", + "Episodes ID": "2d54923e-e329-11ea-91a2-af213003aee3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CAML_Edited_1.mp3", + "Episodes Pubdate Date": "2015-11-06", + "Episodes Summary": "

Caml is a functional programming language that is a dialect of the ML programming language family, developed at INRIA and formerly at ENS.

Gérard Huet is a senior researcher at INRIA, the French Institute for Research and Automation. He helped develop the Caml programming language in the 80s, and has a variety of other accomplishments in the world of computer science, including developing the Coq Proof Assistant System.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Caml with Gérard Huet", + "Episodes Uid": "SED4868575164", + "Episodes Audio File": "f9849384cf8bc1bf49a3672fc04027da.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ld", + "Episodes ID": "2294af28-e329-11ea-91a2-436acce57e4b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Reactconf_Edited.mp3", + "Episodes Pubdate Date": "2016-02-23", + "Episodes Summary": "

React is a set of technologies started by Facebook and open-sourced in 2013. Since then, it has become widely accepted as the best JavaScript library for building user-interfaces. A dedicated community around React has developed as well, and with any large software community, conferences are a necessity.

React.js Conf is a yearly conference in San Francisco where React developers talk about the latest developments in the React ecosystem. React started with user interfaces, but has evolved to be so much more. From data flow patterns like Redux, to hardware libraries and virtual reality–React is no longer just a JavaScript library; it is a philosophy for how to build futuristic technologies today. Brent and Jeff discuss all of this, as well as Exponent, a web development platform for building native mobile apps with JavaScript – using React Native.

Brent Vatne is the organizer of React.js Conf and a software engineer at Exponent.

", + "Episodes Title": "React.js Conf with Brent Vatne", + "Episodes Uid": "SED2441572628", + "Episodes Audio File": "cf00dd7065dd59b28ea4bc0fdc36b9b2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6tf", + "Episodes ID": "ea8405a2-e328-11ea-91a2-47221f500d7e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_17_GreatExpectationsData.mp3", + "Episodes Pubdate Date": "2020-02-17", + "Episodes Summary": "

A data pipeline is a series of steps that takes large data sets and creates usable results from them. At the beginning of a data pipeline, a data set might be pulled from a database, a distributed file system, or a Kafka topic. Throughout a data pipeline, different data sets are joined, filtered, and statistically analyzed.

At the end of a data pipeline, data might be put into a data warehouse or Apache Spark for ad-hoc analysis and data science. At this point, the end-user of the data set expects that data to be clean and accurate. But how do we have any guarantees about the correctness?

Abe Gong is the creator of Great Expectations, a system for data pipeline testing. In Great Expectations, the developer creates tests called “expectations”, which verify certain characteristics of the data set at different phases in a data pipeline. This helps ensure that the end result of a multi-stage data pipeline is correct.

Abe joins the show to discuss the architecture of a data pipeline and the use cases of Great Expectations.

", + "Episodes Title": "Great Expectations: Data Pipeline Testing with Abe Gong", + "Episodes Uid": "SED3393393297", + "Episodes Audio File": "ba065309792e14c586d1e211f57c02cc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 687, + "Episodes ID": "ec4aaa8a-e328-11ea-91a2-9fb55d971578", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_23_KafkaDataPipelines.mp3", + "Episodes Pubdate Date": "2019-09-23", + "Episodes Summary": "

A new software product usually starts with a single database. That database manages the tables for user accounts and basic transactions.

When a product becomes popular, the database grows in size. There are more transactions and more users. A company grows around that product, and the company starts to accumulate more data in different sources. Analytics systems, time series databases, and logging tools start to generate data.

Moving this data around between systems starts to become complicated. Apache Kafka is often used as a system for moving data between these different systems, performing transformations, and generating aggregations and summaries of these large quantities of data.

Robin Moffatt works at Confluent, and has written numerous articles about how to move data between systems and design effective workflows for data pipelines. Robin joins the show to talk about modern data platforms and databases, and the patterns for using Kafka to connect those systems to each other.

If you are interested in learning more about how companies are using Kafka, the Kafka Summit in San Francisco is September 30th – October 1st. Companies like LinkedIn, Uber, and Netflix will be talking about how they use Kafka. Full disclosure: Confluent (the company where Tim works) is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Kafka Data Pipelines with Robin Moffatt", + "Episodes Uid": "SED8100429156", + "Episodes Audio File": "93833fcc0924d366100877503d54542c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ij", + "Episodes ID": "eeba0f72-e328-11ea-91a2-1ffb344fc54f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_28_GoAtUber.mp3", + "Episodes Pubdate Date": "2019-04-01", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Uber’s infrastructure supports millions of riders and billions of dollars in transactions. Uber has high throughput and high availability requirements, because users depend on the service for their day-to-day transportation.

When Uber was going through hypergrowth in 2015, the number of services was growing rapidly, as was the load across those services. Using a cloud provider was a risky option, because the costs could potentially grow out of control. Uber made a decision early on to invest in physical hardware in order to keep costs at a reasonable level.

In the last 3 years, Uber’s infrastructure has stabilized. The platform engineering team has built systems for monitoring, deployment, and service proxying. Developing and maintaining microservices within Uber has become easier.

Prashant Varanasi and Akshay Shah are engineers who have been with Uber for more than three years. They work on Uber’s platform engineering team, and their current focus is on the service proxy layer, a sidecar that runs alongside Uber services providing features such as load balancing, service discovery, and rate limiting.

Prashant and Akshay join the show to talk about Uber infrastructure, microservices, and the architecture of a service proxy. We also talk in detail about the benefits of using Go for critical systems infrastructure, and some techniques for profiling and debugging in Go.

", + "Episodes Title": "Uber Infrastructure with Prashant Varanasi and Akshay Shah", + "Episodes Uid": "SED8272752820", + "Episodes Audio File": "b0f3200c9ce28a48b9e48958217c6f88.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5gy", + "Episodes ID": "eef390a8-e328-11ea-91a2-af31ca6e30b6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ico_bubble.mp3", + "Episodes Pubdate Date": "2019-03-17", + "Episodes Summary": "

This is a post written and narrated by Haseeb Qureshi, a cryptocurrency investor and entrepreneur. Haseeb is speaking at an upcoming Software Engineering Daily Meetup.

We can safely say the ICO bubble is over now.

When the bubble finally popped last year, the “market cap” of all crypto fell over $700B, an 85% drop from its peak in January — steeper than the dotcom bubble’s 78% crash. The media gawked at this collapse, and as usual, proclaimed this was the nail in the coffin for cryptocurrencies.

There’s already been enough hysterics and I-told-you-sos. In this essay, I just want to answer the simple question:

Why did the ICO bubble happen?

It’s easy to believe that the ICO bubble, having taken place on uncensorable public blockchains, was a fundamentally new phenomenon.

The technologies that enable bubbles are always new, but the underlying social dynamics are not. The open and permissionless nature of blockchains allows anyone to co-opt them. Thus, blockchains enabled multiple social forces, all interacting in the same network, all reified under the name “the ICO bubble.”

In this blog post, I’ll examine three major moments in history that illuminate three separate social dynamics that were at play in the ICO bubble.

The first is the peer-to-peer file sharing revolution in the late 2000s, which explains the ideology of decentralization, the proclamations of revolution, and companies trying to circumvent securities laws.

The second is the penny stock boom of the 90s, which explains the casino of shitcoin gambling, market manipulation, and fraudsters that comprised the long tail of ICOs.

And the third is the dotcom bubble, which explains the mass of speculators, the new paradigm of decentralized companies, the VC coins, and the redistribution of wealth.

By exploring these episodes, I hope to show you how the ICO bubble recapitulated well-known patterns of human behavior.

History does not repeat, but there are a few refrains it loves to come back to.

Bitcoin shares deep roots with the P2P networks. File sharing protocols became the world’s first global decentralized networks. Bitcoin’s gossip-based networking model was inspired by Gnutella, the protocol behind LimeWire. Many P2P barons were foundational to the crypto movement: Jed McCaleb of eDonkey2000, Zooko Wilcox of Mojo Nation, and Bram Cohen of BitTorrent to name a few. They also share a philosophical lineage — Lawrence Lessig, the intellectual godfather of piracy culture, is the originator of the phrase “code is law.”

The P2P file sharing revolution began in 1999, with a little application called Napster. On its face, Napster was straightforward: log in, search for a song you want, double click, and it’s yours.

It sounds simple, but it’s hard to describe how large of a paradigm shift Napster was.

Remember what it was like to purchase music in 1999: standing in a CD aisle, surrounded by rows of disc jackets, debating in your head which album to spend your $20 on. Jay-Z? Smashmouth? Or maybe J-Lo? Every purchase was a careful tradeoff. Music was scarce and precious.

Napster changed all that. It was like a bank vault of music was propped open, free for anyone to plunder. Entirely via word of mouth, Napster spread across America like a riot, clogging up bandwidth on college campuses and dialup lines.

Soon, legal challenges from Metallica and Dr. Dre would thrust Napster into news headlines. Napster seized the national conscience. At its peak in 2001, the service had more than 80M registered users. The RIAA took notice.

After a lengthy court battle with the RIAA, a judge ruled Napster liable for all of its users’ copyright infringement, despite the fact that Napster’s servers didn’t host any copyrighted content. This legal doctrine, known as vicarious infringement, was the death knell of Napster and of any file sharing-based business model. Napster was driven to bankruptcy and forced to clamp down on all illegal file sharing. But Napster’s surrender was only the beginning of this war.

To the digital revolutionaries, the lesson of Napster was obvious. Despite all downloads being peer-to-peer, Napster operated a central server, primarily used for search indexing and peer discovery. This was its downfall. If the file sharing revolution were to continue, it would have to decentralize and become resilient to legal injunctions.

A traditional war had to evolve into guerrilla warfare.

Decentralized alternatives to Napster gradually arose, intentionally designed around this legal constraint. Successors like Gnutella (LimeWire) and eDonkey2000 (eMule) would have decentralized architectures that would be much more difficult to take down.

As the children of Napster proliferated, a philosophy began to solidify around internet piracy. Slogans materialized: “information wants to be free,” “open culture,” “sharing is caring.” A new political party called The Pirate Party was formed, championing online freedom and copyright reform, winning multiple political appointments across Europe. Radical innovations in intellectual property were explored such as the Creative Commons and copyleft licensing. The revolution had gained an energy and identity of its own.

BitTorrent, founded by Bram Cohen in 2001, would arguably be the last stage in the evolution of P2P file sharing. The BitTorrent protocol overtook KaZaA, Limewire, DC++, SoulSeek, and all the other P2P networks. By 2012 it’s estimated to have peaked at a staggering 400M-500M monthly active users, almost half of the entire Facebook userbase at that time. During its peak, BitTorrent was by far the single largest source of Internet traffic in the world.

It’s worth asking: why did BitTorrent dominate file sharing while other networks fell into irrelevance?

Simon Morris, a former executive at the BitTorrent company, wrote an excellent four-part tour de force analyzing the parallels between BitTorrent and crypto (if you can’t be bothered to read the whole thing, I encourage you to read its final chapter). I’ll be building upon many of his insights here.

BitTorrent was intentionally structured differently from other P2P file sharing projects. The project’s original home page begins its explanation of BitTorrentlike this:

It is a surprisingly dry, intellectual manifesto.

Compare this to KaZaA’s credo:

Bram Cohen explicitly disavowed all illegal file sharing usage of BitTorrent. He never once acknowledged this as a legitimate use of the service. The core team and their messaging was unimpeachable. And this is precisely what allowed BitTorrent to flourish on the back of all of its legitimate uses: Linux distros, World of Warcraft updates, dataset sharing, and so on.

BitTorrent was never supposed to be a revolution in internet piracy; it was supposed to be a revolution in low-cost file distribution. This unobjectionable mission statement made BitTorrent safely beyond the reach of the RIAA or any other aggrieved copyright holder.

There’s a striking parallel with crypto: Vitalik and the Ethereum core team never endorsed the flood of ICOs — they often denounced them. This is precisely what allowed Ethereum to flourish, despite being subverted by ICOs for speculative and extralegal purposes. If Ethereum did not brand itself as a revolution in decentralized computing, as “the world computer,” it would have been labeled by regulators as an illegal ICO platform.

If you fast forward to today, the story of P2P file sharing is the story of BitTorrent. All other protocols have faded into obscurity. But BitTorrent is no longer used for downloading music in the western world.

Why not?

I’ll give you three reasons: Spotify, Apple Music, Pandora. Newcomers in the music industry have adapted, and these services transformed the experience of discovering and listening to music.

P2P file sharing once competed against the experience of driving to Walmart and buying a $20 DRM-protected CD to listen to a single hit song. Between the two options, the decision was comically easy: just pirate it.

Daniel Ek, the former CEO of uTorrent, understood this firsthand. After witnessing the new decentralized file sharing networks replace Napster, Ek came up with the idea for a company he’d eventually name Spotify:

Today P2P file sharing has significantly declined. But make no mistake: the digital piracy revolution moved industries. It forced music and film to cater to a digital-first world and eventually incentivized the invention of web streaming. The companies that didn’t adapt are now footnotes in history. Those that did will get to build the media dynasties of the next decade.

If you listen to Lawrence Lessig or Peter Sunde, it’s easy to assume the file sharing revolution was rooted in ideology. But few file sharing veterans are still committed to piracy today. Trying to explain file sharing by appealing to intellectual property reform is like trying to explain the Boston Tea Party by appealing to John Locke. Ideology, while important, is usually post hoc.

The real story is much simpler than that.

The file sharing revolution took off because people opposed a rule: you can only consume music how the record industry says you can.

People hated this rule. So they broke it. And P2P protocols enabled this great, overwhelming mob of rule breakers to demonstrate the way they thought music ought to work.

Today, music works that way. No matter where you are, by doing a search and double clicking, you can listen to almost any song ever created.

Simon Morris claims this was the raison d’être of BitTorrent, and of decentralized networks more generally. Decentralization allows rules to be broken. And when a rule is opposed widely and strongly enough, people will build the technology to break that rule, and that technology will spread.

So why did ICOs need to be decentralized? Why couldn’t the bubble have kicked off through equity-backed blockchain startups like in the dotcom bubble?

To Simon Morris, the answer is obvious: because ICOs were not just about the chance to invest in speculative blockchain projects. They were also about breaking rules: the rules around capital formation.

This begs the question, why do people want to break the rules around capital formation so badly?

The answer is complicated.

Consider the initial conditions of the ICO bubble. The bubble was primarily driven by countries in Asia with high savings rates and income inequality — China, Japan, and Korea. Over the last decade, we’ve seen income inequality rising, declines in wage growth for the global middle class, waning trust in governments, and a mass of overeducated young people with shrinking opportunities.

The ICO bubble was a loud rattling of this cage.

The most massive wealth creation events in the world took place over the last decade — but it all went to other people. You didn’t get any. This new wave of technology has subjugated your digital life and attention span, but its fruits belong to the capitalists in Silicon Valley, not you.

The ICO bubble let young people convince themselves: hey, maybe I can get my share. I see this Bitcoin thing, I see this Ethereum thing, they’re so novel and revolutionary, why couldn’t they change the world?

And wouldn’t they get just a little convinced that for once, they were a step ahead of their parents, ahead of the gatekeepers, ahead of Wall Street and Silicon Valley?

So they got in early. They started using VPNs. They got friends and family to create overseas accounts. They broke the rules. And what were those rules good for anyway, besides rigging the system for the rich? Why couldn’t anyone in the world invest in whatever they wanted? Who needs disclosures anyway, if the future is going to be open source?

The market kept proving them right. So they speculated, they joined Subreddits and debated ideas and convinced themselves that their investments would revolutionize the world’s infrastructure. A decentralized future was fast approaching, and they were going to be, for once, at the vanguard ushering it in.

And of course, when reality finally caught up, it showed them the consequences of breaking those rules. 2018 brought everything crashing down, laying bare all the scams, frauds, and widespread market manipulation. A once ecstatic market flattened out like a pancake.

And here we must also acknowledge the other side of the market: entrepreneurs. To them, ICOs represented a great equalizer. After all, ICOs were dispersed internationally, and venture capital is still hard to come by outside of Silicon Valley. In the age of the Internet, in the age of blockchain, why hadn’t technology already leveled the playing field? Why should it matter where an entrepreneur lived or what language they spoke, so long as they knew the language of programming?

With ICOs, you didn’t need an intro to Sequoia to get your company started. Now you simply needed a good idea and a white paper, and the world’s capital would beat a path to your door.

Remember all the stories of VCs quaking in their Patagonia vests, worried that they were being displaced?

And then there were the reverse ICOs, where established companies ICOed their own token, as in the case of Kik or Kakao. This is perfect if you want to fund an internal blockchain-related initiative, but skip all the burdensome overhead of shareholder protections or revenue generation.

Even among startups funded by Y Combinator, the hottest accelerator in the world, I heard reports that a startling number of them were pondering ICOs. Even Silicon Valley elite wanted to break the rules! In this case, they wanted a way out of their illiquid startup ownership, and speculators were all too happy to provide it to them.

It was only in retrospect that they would each realize why these rules were there in the first place. Once again, crypto relearned the lessons that traditional finance had long ago internalized.

Let’s grant that the ICO bubble was instigated by a desire to break the rules around capital formation. Today, with the dust having settled and the ICO bubble now an awkward memory, we can reexamine its battle cries with more clarity.

Did people really care about changing the rules around capital formation? Did they really care about democratizing investing access? Did they really care about reforming accredited investor laws, financial disclosures and AML/KYC requirements?

Many intellectual commentators rallied against these during the run-up, but this too was probably just part of the frenzy of revolution. I don’t see much clamoring for this in 2019.

As for the file sharing revolution — copyright law is, for all intents and purposes, mostly intact 20 years later.

So what does the file sharing revolution tell you about the ICO bubble?

First, it tells you that you should not take ideology at its word. The underlying causes of revolutions are usually more pragmatic than they appear.

It also explains the supply side for ICOs, companies that wanted to circumvent traditional channels for capital formation, and the demand side, individuals who were desperate to get access to high-growth speculative investments. Once the incentive to break the rules has waned, the revolution is likely to stop. That is precisely what we’ve seen in both file sharing and in ICOs.

But there’s another, darker side to explaining the ICO bubble — as an enabler of fraud, manipulation, and gambling. For this, we turn to our second historical model: the penny stock boom of the 90s.

Balaji Srinivasan once claimed that tokens would turn blockchains into the world’s biggest stock market. This may someday be true — but for now, it seems that blockchains have become the world’s biggest penny stock market instead.

The term “penny stock” evokes images of shady stockbrokers in boiler rooms, and for good reason. You’ll remember Jordan Belfort, the protagonist of the 2013 film Wolf of Wall Street, made his fortune hustling as a penny stock broker.

Penny stocks are defined differently in different countries, but in the US, a penny stock is a stock issued by a small company that trades below $5 a share (originally it was stocks that traded below $1, but inflation and all). They are generally quoted OTC and seldom trade on national exchanges. They have low liquidity, little public information, and are not required to make significant financial disclosures.

As such, they are plagued with fraud.

The legal designation of penny stocks began after the 1929 stock market crash, which subsequently triggered the Great Depression. It was believed that the crash was partially caused by unbridled speculation on penny stocks, and this led to the Securities Exchange Act of 1934 designating legal restrictions on penny stock trading.

Throughout most of the 20th century, penny stock offerings could not legally be placed in newspapers. Orders could only be placed via telephone. The highest quality penny stocks would only provide financial reporting once a year, and the very worst penny stocks had no financial disclosures at all. Given these barriers, penny stocks tended not to receive much attention.

But starting in the mid-90s with the growth of the Internet, penny stock trading exploded. Discount brokers emerged, offering automated interfaces and much lower trading fees. As retail investors flooded in, the space grew faster than regulators could track it, and market manipulation became rampant.

Eventually, the SEC stepped in and brought a string of high profile casesagainst Mafia crime families for penny stock manipulation schemes. All of these schemes were ultimately enabled by the Internet: it accelerated the velocity of fraud and allowed bad actors to connect directly with speculators.

Penny stock trading has been brought back under stricter regulatory oversight, but it’s still extremely speculative, and manipulation is common. In 1989, the heyday of penny stocks, a survey found that Americans had been cheated out of at least $2B a year by fraudulent penny stock schemes.

There’s an obvious parallel here with the ICO bubble.

The SATIS group estimated that 81% (!) of ICOs were scams and it’s been widely reported that over $9M was stolen per day in 2018 (annualized, that would be upwards of $3B a year). By sheer number, the overwhelming majority of ICOs can be explained this way. But the parallel between ICOs and penny stocks runs deeper.

Let’s take a step back here and ask: why are people so drawn to penny stocks in the first place, given how fraught they are?

As a former professional poker player, I can tell you the answer is simple: people love to gamble. Humans will forever be drawn to the idea of turning around their fortunes, of outsmarting the establishment, of skipping steps on the social ladder. No matter how much gambling is stigmatized, regulated, or outlawed, it always survives one way or another.

For penny stocks, they tap into the same greedy credulity behind all get rich quick schemes. It hardly matters what the underlying company does.

But we must also acknowledge the other side of this market: the hustlers and fraudsters. To them, penny stocks are a gift. And they also don’t care what the stocks represent — they simply need a company with a ticker and story to manipulate. Greed takes care of the rest.

Reminding you of anything?

Here’s a telling article published in 2000 on common Internet penny stock pump and dump schemes. Let’s contrast it to ICOs.

The modern version: hiring an ICO marketing agency, which will manage your Telegram chat, Subreddit, Medium account, and BitcoinTalk thread.

Don’t have a real community? No problem, buy a fake one.

How about a “hyper-scalable” “quantum-resistant protocol” for “supply chain management”? Getting some credentialed advisors to praise your protocol? Maybe rumored partnerships with a couple Fortune 100 companies?

(many of these examples are drawn from Anatomy of a Pump & Dump Group)

You know the jig. Bounties, referral bonuses, airdrops, presales, advisor shares, purchased reviews, paid followers, social media bots, wash trading, painting TA signals, and so on. By the time the ICO boom had gone mainstream, this procedure was a well-oiled machine.

Most of the long tail of ICOs — and that tail was very long — were complete nonsense. According to most trackers, the total number of ICOs was well into the thousands, and that’s only counting those that were able to rise above the noise.

And like each penny stock boom before it, the ICO boom ended in multiple regulatory actions against the worst offenders. But regulators can’t reach everyone, and most of the pump and dumpers either moved on or continue to manipulate coins at smaller scales.

ICOs, just as penny stocks, are a two-sided market. Speculators don’t care about the technology, they just want tickers to bet on and get rich. Fraudsters don’t care either, they just want tickers to manipulate and get rich. Everyone gets what they need, the market bustles with activity, and everyone makes money — until they don’t.

If you think about it, global, uncensorable blockchains are basically the optimal platform for another penny stock boom. It’s no wonder that bad actors and speculators were quick to converge on it. But despite the technological accoutrements, it’s an old story.

So what do penny stocks explain about the ICO bubble? Penny stocks explain the shitcoins, the scams, the unregistered securities, the market manipulation, and most of the long tail of the ICO bubble. Again, by volume, this is most of what was happening in the bubble.

But I want to be careful here. Penny stock fraudsters were quick to co-opt ICOs, but the concept of an ICO didn’t begin that way. ICOs arose out of blockchain community crowdfunding, first pioneered by Mastercoin in 2013, with Augur being the first ICO on Ethereum in 2015. Most of their investors were nerdy cypherpunks, excited to support some new technology they could play with.

We should not conflate cryptocurrencies, the underlying technology, with the ICO bubble, which was a speculative phenomenon that converged atop it. The ICO bubble was something that happened to crypto, not something intrinsic to it.

Most of the technologists and cypherpunks who built this stuff were simply motivated by building a new financial system. And they’re still whittling away, even after the thundering herd of speculators and fraudsters have come and gone.

So we’ve looked at P2P file sharing and penny stocks in comparison to the ICO bubble. But there’s still one aspect of the bubble that I’ve failed to address so far — technological innovation.

After all, I don’t believe for a second that the crypto boom was principally about defrauding people, or that its underlying technology was irrelevant. The very opposite — the ICO bubble occurred atop the kindling of real technological innovation. To fully understand this, we have to turn to the last historical precedent: the dotcom bubble and its soothsayer, Carlota Perez.

The World Wide Web — the Internet as most people know it — was created by Tim Berners-Lee in 1989. Its invention was the spark that set off the Information Age, and alongside it, the greatest stock market bubble of this generation.

Compared to the technologies that came before it, the Web evolved rapidly. The Internet only had 2% penetration in the US when the Mosaic browser launched in 1993. Six years later, at the height of the bubble, a full 36% of the US was online. (Telephones took more than 30 years to reach the same level of penetration.)

The rapid rise of the Web, combined with low interest rates and the Clinton tax cuts of 1997, led to an incredible bullishness around the growth potential of the Internet. Venture capital became cheap and opportunistic. Entrepreneurs flocked to Silicon Valley.

Netscape, the company that built the Web’s most dominant web browser, kicked off the age. Netscape IPOed for $2.9B in 1995. It was somewhat unusual for an unprofitable company to IPO so successfully, but Netscape’s revenues were growing so rapidly that this would soon be forgotten.

The Netscape IPO would be quickly followed in 1996 by Yahoo!, Excite, and Lycos, all fantastically successful IPOs by companies that were also growing rapidly. And though, like Netscape, they were burning through cash, it didn’t seem to matter. Internet companies had become anointed.

Any company, so long as it had a “.com” in the name, attracted huge valuations. Investors pulled money out of slower-growth companies to plow more capital into dotcoms. Retail investors, having recently received tax rebates, piled in. The Internet itself became the interface for many investors, through platforms like E-Trade (which also IPOed in 1996). Many publications reported stories of white collar professionals quitting their jobs to daytrade tech stocks full-time.

In just five years, the NASDAQ had risen more than 400%. This fomented an all-out frenzy. In 1999 alone, Qualcomm 26X’d its stock price. Analysts stopped emphasizing P/E ratios and began citing Metcalfe’s Law. A WSJ article from 1999 posed the question: are profits just a “quaint concept” that doesn’t matter anymore? The Super Bowl in January of 2000 featured no fewer than 16 dotcom commercials.

Companies like Pets.com were going from incorporation to IPO in a single year. Almost every single IPO popped, with an average of 68% first-day gains. Investing in tech IPOs was widely agreed to be a foolproof way to multiply your money. A phenomenon of dotcom parties spread across the valley, and those close to founders often received “friends and family” shares as tokens of generosity.

It was a time of excess. The trend was baffling to Wall Street, to the East Coast elites, to the old money. Storied hedge funds like Tiger Management went under, unable to keep up with the shifting market structure. But the techies — they knew it all along, they told themselves.

The Internet would change everything.

On March 10 of 2000, the NASDAQ would hit its peak. The first tremor of weakness was on April 14, likely triggered by a tax selloff. By the end of that week, the NASDAQ tumbled a staggering 25%.

Soon, dotcoms realized that their burn rates were unsustainable. The Fed announced plans to aggressively raise interest rates, and the economy would see six such tightenings over the next several months. Capital wavered.

By May 18th, Boo.com went bust. In November, Pets.com followed. A few months later, Webvan shuttered operations. The show came crashing down faster than it had started, and funding had all but vanished. By the end of 2001, after the September 11 attacks, most publicly traded dotcoms went bankrupt. Trillions of dollars of investment capital had evaporated.

The ensuing recession would last several years. It wouldn’t be until 2004 when the first major post-crash dotcom company, Google, would IPO again.

Its first day pop was 18%.

With hindsight we can say that investing in the Internet was clearly right. It’s obvious how dramatically the Internet has changed the world. And yet the dotcom bubble seemed to have veered off somewhere terribly wrong.

What happened? Why couldn’t people at the time see it? And what can it teach us about the ICO bubble?

To understand the dotcom bubble, we have to start with Carlota Perez.

Carlota Perez is the patron saint of venture capitalists. Her seminal work, Technological Revolutions and Financial Capital has been been cited by Marc Andreessen and Fred Wilson as pivotal to their understanding of the tech industry.

I won’t do her book justice here, but I’ll attempt to summarize the key ideas that are relevant to both the dotcom crash and the ICO bubble. I’ll be quoting heavily from Carlota herself.

Carlota Perez subscribes to the long wave economic cycle theory, known as Kondratiev Waves, in which technological innovation occurs in 45–60 year waves.

According to Perez, these innovation waves consist of three phases:

Installation is the period when a new technology is first explored, installed, and then speculated on. This speculation leads to an unsustainable asset bubble and a spectacular collapse. Then a more sober period of deploymenttakes place, during which the technology matures and sustainably alters many aspects of society. After a full deployment cycle has exhausted its economic growth, a new technology initiates a new innovation wave, and the cycle begins anew.

The same general shape can be observed in each cycle.

Each of these revolutions was kicked off by a seminal project that would catalyze the technology — the industrial revolution with Arkwright’s Cromford mill, the steam and railway age with the Liverpool-Manchester Railway, the steel and heavy engineering age with Carnegie’s Bessemer steel plant, the age of automobiles with Ford’s assembly line, and the computer age with Intel’s 4004 microprocessor.

By this model, the moment that kicked off ICO bubble must be the launch of Ethereum. Ethereum was not the first cryptocurrency, but it was the first ICO to produce astronomical returns, and it would set the foundation for the frenzy that was to come. Ethereum launched in 2015, exactly 44 years after the Intel 4004 in 1971.

What does she mean by “techno-economic paradigm”?

Simply put, a techno-economic paradigm is a new accepted way of doing things. When a new technology takes form and begins driving innovation, it brings with it a new logic of how businesses should be structured. For example, with the advent of the automobile, the paradigm encouraged businesses to adopt mass production, economies of scale, and standardized products for mass marketing appeal — the logic of the factory. In this paradigm, every American should own not just a mass-produced automobile, but also a TV, a refrigerator, a washing machine, etc.

As a techno-economic paradigm becomes ascendant, any entrepreneur who does not subscribe to the new paradigm will be seen as low-status and behind the times.

We know the techno-economic paradigm of the late internet revolution: move fast and break things, launch MVPs, iterate in short cycles, pursue business models with zero marginal cost. Basically all the mantras consumed today by aspiring tech founders.

Cast in these terms, the techno-economic paradigm of crypto is almost embarrassing to say out loud. Here’s what we taught founders about how to build a business in the crypto age:

Basically, cargo culting the Ethereum ICO—the same way dotcoms cargo culted Netscape.

In the ICO bubble, founders who deviated from this paradigm were seen as low-status, opportunistic, “not getting crypto,” and were thus less rewarded in their fundraises. Yet in hindsight, almost none of this was predictive of an entrepreneur’s long-term success.

Keep the dotcom crash in the back of your mind. For now, I’m going to focus entirely on how Perez’s account of financial bubbles comports with the ICO bubble.

In the frenzy, new millionaires are minted. They try to multiply their wealth in the same way they made it, redeploying their capital to generate more profits. The gap between paper values and real values widens, and the newly rich come to believe that their newfound wealth is due to superior insight and intuition.

Dismantles institutional frameworks, check. Overinvests in new infrastructure, check. Invents new instruments for financial speculation (ICOs, SAFTs, SAFTEs), check.

Do you remember being told by Uber drivers to invest in BAT or IOTA? Do you remember the New York Times article, Everyone is Getting Hilariously Rich and You’re Not?

Perez recalls a quote by Bruce Nussbaum about the dotcom bubble:

Do you remember the nonsensical projects? The teams that no one had heard of? The copy and pasted white papers? All the shameless rhetoric about 10 trillion dollar TAMs and 100K transactions per second?

Do you remember all the ICO investing syndicates? The Telegram groups? The newsletters?

During Canal Mania in the 1790s, canals were created from river to river with no regard for routing, believing that canals magically produced demand. In the 1840s, railway projects were built from town to town without regard for engineering practicality. In the 1920s, real estate values became untethered from the constraints of urban planning, believing that the automobile meant any territory could be valuable if connected by roads. And of course, in the late 90s, dotcoms were funded with no evidence of product-market fit.

None of this is new.

And of course, do you remember all the voices (rejoicing and lamenting) the new redistribution of wealth?

The ICO bubble was simply a variation on the theme. The players and the tactics were different, but the human stories were the same. Like in the dot com bubble there were, as always, stories of overnight millionaires, flagrant scams, manifestos declaring a new technological order, levered debts and second mortgages that ended in catastrophe — all the usual roil and ruin of speculative manias.

All this is to say, we’ve seen this before.

Crypto’s gilded age is probably now over. Most of those newly minted millionaires have unwittingly surrendered their riches. The hype has died away, ICO funding has dried up, SEC enforcement actions are trickling in, and the media’s crush on crypto has passed.

But, Perez reminds us, the frenzy phase and subsequent crash is not merely painful — it is necessary to any technological revolution. The financial casino attracts the funds necessary to install basic infrastructure and facilitate social learning.

Without the dotcom bubble, there would not have been all of the investments into optical fiber buildouts, ISPs and internet infrastructure, packet-switched networks for telecoms, and all the competition overs consumers that would ultimately galvanize internet adoption. We needed that social and technological foundation in place for the Internet to flourish.

Perez’s book was written in 2003 during the nadir of the dotcom crash, and she presciently situates the Internet within her K-wave framework. History has proven her right.

But we should be careful not to invert her thesis: she claims that all technological revolutions induce a bubble, but that does not mean all bubbles are induced by technological revolutions. Indeed, most aren’t. It remains to be seen which camp crypto falls into.

So what does Perez explain about the ICO bubble?

She explains the logic of frenzy, the stoking of financial capital, and the rhetoric of paradigm shifts (“all companies will become decentralized”). She explains the influx of retail investors (“widows and orphans”), traditional financial capital piling in at dizzying prices (Telegram, Filecoin, Hashgraph), and the flood of traditional entrepreneurs contorting themselves to follow the new paradigm.

In the end, we should count ourselves lucky that the ICO bubble was not as destructive as the dotcom bubble. About $15B were raised by ICOs in 2017–2018, but that’s a drop in the bucket compared to all of venture capital, which deployed around $500B during the same period. And the ICO crash was not nearly as destabilizing as the dotcom bubble. When all is said and done, the dotcom bubble wiped out about $5 trillion of value and was much more concentrated in the United States. Losses in the ICO bubble were ~15% of that, absorbed across many more economies, and during a time of relative economic prosperity. (Also, we should be cautious when conflating the “market cap” of crypto with the NASDAQ.)

The ICO bubble had no single cause. Mono-causal explanations always fall short in explaining complex phenomena. But its effects are easier to pinpoint.

There are now many world class teams well-capitalized to build, scale, and evolve blockchain technology, and tens of millions of people in the world who now understand decentralization, proof of work, and private keys. Looking back, it’s really quite amazing! It comes at a high cost, but Perez hints: it’s likely that bubbles like these are the only way to overcome technological inertia.

At the same time, most people had their first interaction with crypto during its orgiastic adolescence. It’s not a great look. But this has been true for every technological revolution of the last 250 years. In that regard, crypto is in good company.

I was too young to appreciate the dot com bubble when it happened. It’s strange to say, but I’m glad to have witnessed a speculative bubble from up close. I’ve now got war stories to share with future generations. It was a wild time, when anyone in the world could launch a coin and raise tens of millions of dollars to build a network that no one could control. I don’t think we’ll see anything like that again for a long time.

So what happens now?

If you believe that crypto has the stuff of a technological revolution, then as Perez puts it, the collapse will pave the way for a more fruitful deployment phase. At the end of the day, I’m an optimist about technology. So it won’t surprise you that I think this deployment phase is coming. But it will be slow, unglamorous, and probably won’t make for nearly as entertaining of headlines.

Oh well.

", + "Episodes Title": "Crypto Bubble with Haseeb Qureshi", + "Episodes Uid": "SED6191982396", + "Episodes Audio File": "fefe3451abd965e99986a3372f73c8ab.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 620, + "Episodes ID": "ecd03dd0-e328-11ea-91a2-db082bc9b9a3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_12_BigBusinessTylerCowen.mp3", + "Episodes Pubdate Date": "2019-08-12", + "Episodes Summary": "

Large software companies have become a target for criticism. Google, Facebook, Amazon and other prominent technology giants find themselves under a kind of scrutiny that is reminiscent of banks in 2008 and oil companies in the early 1900s. Across the planet, there is a growing sentiment that “big tech” has too much power, and that they are abusing that power in order to dominate markets, censor speech, and manipulate politics.

Tyler Cowen is the author of Big Business: A Love Letter to an American Anti-Hero. He is also the host of the popular podcast Conversations with Tyler and an economist at George Mason University. In Big Business, Tyler explores the modern relationships between consumers and businesses, including the large technology companies.

Tyler joins the show to discuss his new book. In previous episodes with Tyler, we also talked about his previous books as well as the effects of technology on American society and the philosophical approaches software engineers can bring to their careers.

", + "Episodes Title": "Big Business with Tyler Cowen", + "Episodes Uid": "SED2613286426", + "Episodes Audio File": "0dc9a3aec119abbcb37df833b5876be2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23b", + "Episodes ID": "191ea138-e329-11ea-91a2-d7f094bd2fb0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/database_crisis_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-07-19", + "Episodes Summary": "

Breakthroughs in modern data research tend to come from companies like Google, Facebook, and Amazon, with projects like MapReduce, Cassandra, and Dynamo.

Twenty years ago, this types of breakthroughs would be happening in academia, which causes today’s guest Peter Bailis to ask: is the academic data community having an identity crisis?

Peter is an assistant professor at Stanford University, where he works on an analytic monitoring system called MacroBase. Our conversation also explores the intrigue and the challenges of analyzing and storing IoT data.

", + "Episodes Title": "Peter Bailis on the Data Community’s Identity Crisis", + "Episodes Uid": "SED7755190617", + "Episodes Audio File": "3af2e0730d3a93599b7c3bb95b9a3d8a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ch", + "Episodes ID": "0ec5b9d8-e329-11ea-91a2-ff1df1604ff0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/cloudfountry_edited.mp3", + "Episodes Pubdate Date": "2016-12-12", + "Episodes Summary": "

Cloud Foundry is an open-source platform as a service. Companies use Cloud Foundry as a control plane to deploy and manage applications. It provides abstractions for microservices and continuous integration.

Cornelia Davis joins the show to discuss Cloud Foundry. I interviewed her at the DevOps Enterprise Summit, where enterprises share their stories of improving their culture and their technology stack. Cornelia explained how and why a large enterprise adopts Cloud Foundry, and why they often hire a company like Pivotal to help them as they migrate their infrastructure and change their processes.

", + "Episodes Title": "Cloud Foundry with Cornelia Davis", + "Episodes Uid": "SED8100456031", + "Episodes Audio File": "3a6bc51cc116cced11ccd9e2d4178847.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25u", + "Episodes ID": "15828fa8-e329-11ea-91a2-537ec71ae106", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Facebook_Relationships_Fixed_Edited.mp3", + "Episodes Pubdate Date": "2016-09-06", + "Episodes Summary": "

Facebook users provide lots of information about the structure of their relationship graph. Facebook uses that information to provide content and services that are expected to be important to users. If Facebook knows who the most important people in my life are, Facebook can use that knowledge to serve me content that is more relevant to me.

Jon Kleinberg studied Facebook network structures together with Lars Backstrom, creating a paper called “Romantic Partnerships and the Dispersion of Social Ties: A Network Analysis of Relationship Status on Facebook”. The goal of this study was to find a metric that could help rank the strength of relationships on Facebook, and the results have implications for sociology as well as the way that we think about building social networks.

Jon is a professor of Computer Science at Cornell, and wrote the textbook “Algorithm Design” which I used in college, so it was a privilege to get to talk to him.

", + "Episodes Title": "Facebook Relationship Algorithms with Jon Kleinberg", + "Episodes Uid": "SED8940132420", + "Episodes Audio File": "b75f05c2145bf749f9c76095983ac719.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ei", + "Episodes ID": "ef176a78-e328-11ea-91a2-375a5665ddd1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_06_Pinot.mp3", + "Episodes Pubdate Date": "2019-03-07", + "Episodes Summary": "

Monitoring tools are used by every area of an organization.

Business development teams use monitoring to understand the metrics for product performance. Finance teams need to understand how the costs of cloud computing resources are changing. Site reliability engineers use monitoring dashboards that applications are up and running without problematic latency. Product managers evaluate the results of AB tests based off of the monitoring data of how users are reacting to new features.

A monitoring system needs to be able to handle large volumes of data that are being generated at a high velocity. The data needs to be queryable in an aggregated format, which might require an ETL system for getting data into columnar format.

Alexander Pucher is an engineer at LinkedIn, where he works on a monitoring platform called ThirdEye. ThirdEye is built on top of Apache Pinot, a distributed columnar storage engine that ingests data and serves analytical queries at low latency. Pinot uses RocksDB, and is comparable to Apache Druid.

Alexander joins the show to discuss ThirdEye, and explain why Pinot is a useful building block for monitoring infrastructure.

", + "Episodes Title": "LinkedIn Monitoring Infrastructure with Alexander Pucher", + "Episodes Uid": "SED1543191462", + "Episodes Audio File": "22f0b89b833eaea63607de3e243709c4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1r9", + "Episodes ID": "20424500-e329-11ea-91a2-7be19b2ca944", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/opcode_fixed.mp3", + "Episodes Pubdate Date": "2016-03-21", + "Episodes Summary": "

Military veterans have the right set of skills to become programmers. Technical expertise, emotional resilience, psychological persistence, and teamwork–these are the qualities of the US army and they are the qualities of the best programmers. More and more veterans who leave the army are becoming coders, and the mission of Operation Code is to help veterans make that transition.

Dave Molina is the founder of Operation Code. His organization helps army veterans become coders. Dave came on the show to discuss coding boot camps, military, software education, and what it’s like to become a civilian technologist after spending years in the army.

", + "Episodes Title": "Helping Veterans Learn to Code with David Molina", + "Episodes Uid": "SED6628797046", + "Episodes Audio File": "f06f00e0fd72a83d415d5dec76d6af7e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2bi", + "Episodes ID": "0f6fd4fe-e329-11ea-91a2-73b50a113e46", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/adforprize_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-12-03", + "Episodes Summary": "

There are multiple paths to constructing a piece of software from start to finish.

An individual programmer can build an entire product from scratch in a couple days. A giant corporation can commission a project and delegate responsibilities to hundreds of people. An open source community can use the wisdom of the crowds to efficiently build an operating system.

Today’s episode is about another path for building software, and my own experience traveling that path. I designed and contracted an app called Adforprize that is now available on the iOS app store.

Designing an app and contracting it out to an engineer to build is a worthwhile exercise for most people in the tech industry–whether you are an engineer or not.

This post has two main arguments:

As with the previous monologue episodes such as 10 Philosophies for Engineers and You Are Not a Commodity, there are no advertisements on this episode. Please email me any feedback you have–jeff@softwareengineeringdaily.com

Everyone has an app idea, and many of them are pretty good.

You have probably had a conversation with a friend where one of you says “hey, wouldn’t it be great if there was a 2-sided marketplace for bacon?” Or “hey, wouldn’t it be great if there was an app where users could take a selfie and instantly see what celebrity they resemble the most?”

These things would be cool! But most ideas end with the ideation.

Who has the time to implement these things? Most of us are busy at
\nwork, where we spend our time and mental energy dealing with the technical complexity of our jobs.

If you are a “smart creative”, when you get home from your job, you probably don’t want to spend your leisure hours reading iOS documentation and slowly learning to write the necessary code for your bacon marketplace app.
\n

Smart creatives who have a busy full-time job often have a hobby with more immediate gratification, like playing an instrument or blogging. Some of us also write apps on the side, but if you don’t already have all the requisite skills for writing an app, the prospect of reading tutorials and documentation can make the feeling of ever publishing an app seem so distant.


\nThere are many people listening to this who are
\nbetter at sales, marketing, design, or product management than they are at programming–they want to build an app. One common narrative is that if these people want to see something built, they need to learn to program, and that’s not true.


\nThere is a more fun, fulfilling way to build an app than learning to code in Swift or React Native–contracting out the programming to someone else.

Designing an app is a fun exercise. Building a prototype with tools like Sketch, InVision, and Keynote is free and frictionless. Most people listening to this probably spent some time drawing in KidPix or Microsoft Paint or PhotoShop when they were a kid.

Most of us know how to draw at some basic level, because we spend all

day seeing and understanding images–drawing is second nature to anyone who can understand shapes. Similarly, we all know how to design apps because we spend all day using them. We understand the purpose of a button or a slider or a swipe.

But most of us have no idea how to configure the code around this user experience–the buttons and sliders and TextViews.

Along with the design process,   the business ideation process is also fun. It’s fun to imagine business models and viral loops and ways to drive user engagement. But without the capability to build the app that embodies your business ideas, it is less fun to think about those ideas. And again–most of us don’t relish the idea of struggling through the compiler errors and Stack Overflow posts that an app implementation requires.

We’ve all become product designers. We are using our phones all day–most of us have naturally developed a good intuition for how an app should function.

Product design ability is naturally acquired by being steeped in technology all day. If you are an employee in marketing, sales, or design (and certainly engineering) at a tech company, you will naturally learn how to think about product.

Importantly: you probably even have a few good product ideas yourself!

This article is about why and how to prototype your own ideas and communicate your intent as a product designer–which is an incredibly fun process.

If you can afford it, you can then hand off your prototype to a contractor for engineering implementation.

Working at a tech company, you might have accumulated some excess cash. You can invest that $5,000 that you have sitting around by contracting a product in your spare time. This can be a much better investment than something like stocks or ETFs, and it is more satisfying and durable than taking an expensive vacation.

The experience of contracting a product teaches you skills that might not be stressed in your 9-5 job: management, product design, user experience, budgeting, communications, and engineering limitations.

The first version of Uber was written by a contractor. The Uber founders clearly communicated the specification for their product to the contractor, and they got what they asked for.

Contracting Uber was easy for the founders. They had millions of dollars from their earlier startups, they had a network of contractors to choose from, and they had experience hiring people.

There is now a set of technologies that are enabling this for the average person.

The last point deserves further emphasis. Cool new apps are often interesting remixes of well-defined mechanics.

Mechanics such as newsfeeds, likes, photo sharing, map-based ride-sharing overlays, swiping interfaces, and social media integration are a palette of interesting ingredients that have lots of new-product mileage left.

These types of features are so widely used that their implementation is well-understood and documented. You don’t need to find an expensive contractor who specializes in swiping or newsfeed architecture–you will be paying a reasonable market rate.

Programming ability is not a prerequisite for being a good product designer and operator.

And yet–the negative term “wantrepreneur” is used to describe someone who has ideas but has not built/shipped anything substantive. If you listen to Silicon Valley type of podcasts, you will occasionally hear a venture capitalist or angel investor use the word.

It’s offensive and shame-inducing and should be removed from our lexicon.

But–it does accurately describe many people in the tech industry (albeit in a condescending and discouraging manner). Oftentimes, this same type of person wants to know what to do if they cannot find a “technical co-founder” (someone to build and iterate on a product).

Contemporary product development literature mostly advises against contracting, but it can be a good strategy if you have a product idea you really want to get out the door into the hands of users.

The conventional reasoning against hiring a contractor to build your product (and why it is mistaken):

In today’s tech scene, there are tons of people without the ability to code who nonetheless have excellent product design abilities.

Whether you are in sales, marketing, or customer service, if you want to build a product someday, or even if you just want to move from your current role to a role in product management or design–consider designing and prototyping an app, and having a contractor build it.

If you have specific ideas for what you want built, and you have some extra cash lying around, contracting an experimental app is awesome.

There are plenty of programmers whose job roles do not require them to think about product design.

I spent three years engineering backend Java systems, and there was rarely an interesting decision to be made about the end user’s experience with the product itself. It was all about implementation.

You can spend a whole career like this, never grappling with problems higher up the stack. If you are planning to do that, then you will make a lot of money–why not spend $5k of it delegating an app to a contractor?

You might find out that you love product design and development even more than backend engineering.

I’ve been thinking about contracting an app ever since I heard the story of Uber’s prototype. More recently, when Seth Godin came on this podcast, I asked him about the engineering challenges of building Squidoo, the second company he sold. As it turns out, the minimum viable product for Squidoo was also written by a contractor.

My biggest takeaways from that brief discussion with Seth: have your deliverables as well-defined as possible and you won’t have to iterate in order to get the product out the door as you imagined it in your head.

The Uber and Squidoo examples are interesting because Kalanick and Godin both studied computer science, but they still opted not to write their apps. They decided the work would be done faster and more effectively if they delegated.

As an engineer, I have been building janky minimum viable products for the last five years because I assumed that was the way it had to be done. Each time I designed and built an app, the end result was unimpressive. Because I wasn’t focused entirely on the product design OR the engineering, I did a poor job trying to do both.

This is one of the most common fallacies that keeps programmers in a position where they have to take orders.

The programmer is conditioned to believe that delegating something means admitting that you are incapable of doing it. Programmers are taught that it is more valiant to spend hours reading documentation and doing something on your own than to delegate your work to someone who won’t have to read as much documentation, and will do it faster and more cleanly.

After hearing about several stories of contracted products that turned into successful companies, I decided to experiment with the contracting process myself. I would focus on product design and hire a contractor to write the software.

When we think of product designers, we often think of a bolt of inspiration coming to an inscrutable genius like Jack Dorsey or Steve Jobs or Elon Musk.

The reality is that effective product design can be learned by anyone who is willing to put in the hours, study the craft, and iterate. From Airbnb to Facebook to the wide range of products on IndieHackers.com–successful products come from people are constantly experimenting and toying around with new ideas.

A product designer lives and breathes research and development. The effective product designer is constantly studying the world and running experiments in her own life. She crafts her environment to be conducive to new ideas, and keeps her calendar peppered with blank space where she can reflect and let new ideas come to the surface of her consciousness.

I keep whiteboards around my apartment to write down product ideas and other fleeting moments of inspiration.

Back in college, I was on a diet of homemade Soylent and I was having awful fever dreams due to related indigestion. I had misread the recipe for Soylent that I found online, and had accidentally put three times the amount of fiber in my mixture as the recipe called for.

I woke up at 2 AM from these Soylent induced fever dreams. I have heard that people often think up their best ideas when they wake up at 2 AM, because the boundary between your consciousness and your unconsciousness retreats a little bit.

In this case, I was struck by an idea for a user-generated advertising platform, where companies would offer contests where people could compete to make the best ads. I sketched it on one of my whiteboards and went back to sleep for a few fitful hours.

When I woke up, I copied the idea from my whiteboard to a spiral notebook, and then forgot about it.

Years later, I was working at an advertising technology company, and I started to see some of the inefficiencies in the advertising industry. I realized that my idea from back in college might actually have merit. I started building a prototype called Banner Warhol, and I completed it in a few weeks.

Along the way, I seeded it with some fake ads I made (thanks to Michael Rosenthal and Josh Stewart for helping with the design).

This was a decent idea, but fraught with mistaken execution:

I didn’t know what I was building or why. I had a vague sense that user-generated advertising could be cool, and I started hacking on the idea without thinking further.

I have no professional experience writing front-end apps, and it shows with Banner Warhol. Consequently, the code base quickly became a disaster. I got sick of the project, and I quit: the classic abandoned side project.

As I said above, in this case the engineering was a distraction from thinking about the product. I was afraid to think too deeply about the product I wanted to build because I was afraid I wouldn’t be able to engineer it.

If you are trying to play both product designer and engineer, there can be inherent cognitive dissonance.

I abandoned the idea for a year and a half, going to work at Amazon and then focusing on building this podcast.

But–the idea of user-generated advertising has stuck with me, and when I read futurist Kevin Kelly talking about it in his recent book The Inevitable I knew there was something yet unexplored:

“With a peer-to-peer system, these ads would be created by passionate (and greedy) users and unleashed virally into the blog wilds, where the best ads would evolve by testing and redesign until they were effective.”

If you replace the word “blog”, with “social networking”, the idea for peer-to-peer advertising becomes quite compelling. Social networks are where advertising is most effective today–so the question became, how can you build user-generated advertising into the social network ecosystem?

Snapchat has added features around user-generated advertising and Instagram models make deals with advertisers. These ideas scratch the surface–but user-generated advertising is not just a feature, or an idea that you patent. It is an entire medium of expression.

We need an entire platform for making ads.

People should be able to make advertisements for products, ideas, and movements. They should be able to see each other’s advertisements, to Like and Comment on them, and connect with brands who want to use those advertisements. This would lower the cost to the brands who currently work with overpriced agencies to make their ad campaigns.

Armed with this hypothesis, I thought about the minimal way to run an experiment.

Who is a user base that is most likely to latch on to a product that lets you make ads?

I was thinking about this question when I was scrolling through Instagram and saw a cache of people who are making their own ads already–Instagram fitness instructors and models.

Many of these people are trying to build a personal brand, and in doing so they advertise for products like protein shakes, meal plans, and fitness programs. They may have 2000-5000 followers, which is respectable but not highly monetizable. Most big brands will not do business with this type of person.

Nonetheless, they are “influencer marketers”. This mid-level amount of “influence” is going largely uncaptured. It is like blogging before Google AdSense.

From Instagram to Vine to YouTube to Facebook, there exists the challenge of connecting influencers to brands they should be representing, but on Instagram this problem seemed most acute.

My idea for a workflow was:

It would have the familiar mechanics of a photo sharing app so that people felt like they were using something they had used before.

I took out a notebook and started drawing diagrammatic ideas. When I had the idea fleshed out on paper, I moved to Sketch, a Mac OS tool that is like Photoshop. Stitching together pictures from Google Images, I made the design as crisp as I could.

I had no prior experience with Sketch. It is an awesome piece of software and is more intuitive than I expected.

After creating screenshots for the workflows I wanted, I put together an Invision to further describe the functionality of the app. Invision is a fantastic product for communicating UX and design.

I like Invision because it is easy to share your prototype. At Apple, product designers use Keynote to create prototypes that feel like apps, so that is a viable choice as well.

When I finished the prototype, I wanted to get it into the hands of users. But, I was working on Software Engineering Daily full-time. I already had a lot on myplate, so it was important that I used my spare time efficiently.

For a few weeks, I tried to learn modern iPhone programming. My pace of learning was so slow and I was not motivated by learning the syntax and the design patterns of mobile development. Thinking back to how Uber and Squidoo were made, I decided to contract my advertising platform–which I was then calling “Adstagram”.

I logged onto Upwork and searched for iOS developers with experience on photo sharing apps, quickly finding someone who was top rated and worked for $66/hour. I asked him for a demonstration of his work and he showed me a photo sharing app he had built in the past, which he could reuse some of his code from.

I sent him the prototype and asked him for a quote as well as a description for how he would build the app. His price was reasonable and the architecture he proposed was simple, so we got started with a first, simple set of milestones to hit.

As a software engineer, it was easier for me to evaluate that his estimations of time and cost were reasonable. If you are not an engineer, you can check with an engineer friend to see if what a contractor is offering you is fair.

Upwork creates an escrow transaction for each set of milestones you define. I defined milestones in terms of high-level functionality and capabilities that were a subcomponent of that functionality.

For example, the following list of user story functionality requirements could make up a milestone:

Each milestone was a small amount of money, and gave me a feel for the pace at which the contractor worked, and helped me predict what the final budget might be. After each milestone, he sent me a working version of the application thus far.

I was testing the app after each milestone, and this put me in the shoes of the user. During testing I identified an issue with an image search feature within the app. I made a flow chart in Gliffy to be clear about how I thought it should work.

Four months after initially contracting the app, the functionality is complete and the price tag is under budget–it took $3100 to build, and I gave the contractor a $400 bonus for doing a great job and being responsive.

You can now download Adforprize in the iOS app store. I use the app on a regular basis, and I’m looking forward to seeing how people respond to it.

If you have an iPhone, I would love if you checked it out, and if you like it then rate the app on the app store. I didn’t ask for ratings on the iTunes store very often for this podcast–because I’m not convinced ratings matter that much for podcasts. But they definitely matter for apps.

For many people, the most coveted job in tech right now is “product”, whether that means product design, product engineering, or both.

We dream about drawing something on a whiteboard in a conference room during a meeting, and then seeing a finished product come across our desk a week later, so we can evaluate it, critique it, and send it back for another iteration.

How do those whiteboarding product phenoms get such an awesome job? By practicing and getting good. Why else would anyone talented follow their lead? One way or another, these “product” people have accrued experience and are rewarded with responsibility.

Adforprize has gone from being Soylent-induced nightmare idea to a reality that you can download from the app store. Now begins the long, cyclical slog of getting people to try it out, realizing that numerous UX issues make it confusing and terrible, and paying a contractor for continued alterations.

My hope is that the app gets some traction, and it will make sense to hire someone full time to work on it. If Adforprize falls completely flat, and nobody cares about it–that’s OK too. I have had a ton of fun building it, and the education was worth twice the price. I’m happy to pay the cost of tuition.

", + "Episodes Title": "Adforprize", + "Episodes Uid": "SED3452535758", + "Episodes Audio File": "4c2877a0b1d978a52f0cd5b1f90a8e7f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2rz", + "Episodes ID": "fa1dcfe8-e328-11ea-91a2-0f65cb5abbd1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/objectsegmentation.mp3", + "Episodes Pubdate Date": "2017-06-05", + "Episodes Summary": "

Video object segmentation allows computer vision to identify objects as they move through space in a video. The DAVIS challenge is a contest among machine learning researchers working off of a shared dataset of annotated videos.

The organizers of the DAVIS challenge join the show today to explain how video object segmentation models are trained and how different competitors take part in the DAVIS challenge. A good companion to this episode is our discussion of Convolutional Neural Networks with Matt Zeiler.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Video Object Segmentation with the DAVIS Challenge Team", + "Episodes Uid": "SED7815617892", + "Episodes Audio File": "5e4e8d59b807f9cb93ed3fa7e89b49f4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ou", + "Episodes ID": "fd8b9cb4-e328-11ea-91a2-2ba0c15eff66", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/dataintensive_edited_fixed.mp3", + "Episodes Pubdate Date": "2017-05-02", + "Episodes Summary": "

A new programmer learns to build applications using data structures like a queue, a cache, or a database. Modern cloud applications are built using more sophisticated tools like Redis, Kafka, or Amazon S3. These tools do multiple things well, and often have overlapping functionality. Application architecture becomes less straightforward.

The applications we are building today are data-intensive rather than compute-intensive. Netflix needs to know how to store and cache large video files, and stream them to users quickly. Twitter needs to update user news feeds with a fanout of the president’s latest tweet. These operations are simple with small amounts of data, but become complicated with a high volume of users.

Martin Kleppmann is the author of Data Intensive Applications, an O’Reilly book about how to use modern data tools to solve modern data problems. His book includes high-level discussions about architectural strategy, and lower level discussions like how leader election algorithms can create problems for a data intensive application.

If you are interested in hosting a show for Software Engineering Daily, we are looking for engineers, journalists, and hackers who want to work with us on content. It is a paid opportunity. Go to softwareengineeringdaily.com/host to find out more.

The Software Engineering Daily store is now open if you want to buy a Software Engineering Daily branded t-shirt, hoodie, or mug and support the show. 

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Data Intensive Applications with Martin Kleppmann", + "Episodes Uid": "SED6657827177", + "Episodes Audio File": "e747798f027edc88142e83cd0a9d7fea.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24c", + "Episodes ID": "175adce0-e329-11ea-91a2-c3852ebaee01", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Podcast-tech_Edited.mp3", + "Episodes Pubdate Date": "2016-08-09", + "Episodes Summary": "

The technology underlying podcasts is simple–a podcaster publishes mp3 files to an RSS feed, and the listener subscribes to that feed, receiving mp3s whenever the feed is updated. Unfortunately, the simplicity of podcasts makes it difficult to build automated advertising infrastructure on top of that simple RSS model. This lack of rich automated advertising has kept podcasting from flourishing.
\naCast is a company that is trying to change that by providing a better podcast experience for both the publisher and the listener. Today’s guest Mikael Emtinger is a creative technologist at aCast, and we discuss the infrastructure around podcasts, and how aCast is trying to improve it.

", + "Episodes Title": "Podcast Infrastructure with Mikael Emtinger", + "Episodes Uid": "SED2208064181", + "Episodes Audio File": "89b6b233a17fdb122e07142d50044c30.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "zk", + "Episodes ID": "2b819ed4-e329-11ea-91a2-db05237c12b2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Taming_Text_Edited.mp3", + "Episodes Pubdate Date": "2015-11-20", + "Episodes Summary": "

Information retrieval and search engineering are becoming more intertwined with machine learning and natural language processing, leading to a wealth of work to be done in the field.

Grant Ingersoll is a founder and CTO of LucidWorks, which helps clients make sense of their data and deploy search applications built on Apache Lucene and Solr.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Taming Text with Grant Ingersoll", + "Episodes Uid": "SED7718114676", + "Episodes Audio File": "be0f2387ea632581ca8e5a0ef7f34952.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1zj", + "Episodes ID": "1c4f821e-e329-11ea-91a2-6f49017ae43e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/minecraft_final.mp3", + "Episodes Pubdate Date": "2016-05-26", + "Episodes Summary": "

Minecraft is a sandbox video game in which players build constructions out of 3-D cubes in a procedurally generated world. Minecraft is the best-selling PC game of all time. But Minecraft is not just a game. It is a platform for creativity, used by players within the game as well as programmers outside of it.
\nGabriel Simmer is a 16-year-old programmer who build NodeMC, a tool that wraps around the Minecraft server process. NodeMC can be used to build dashboards for Minecraft, and spin up additional Minecraft servers. In our conversation, Gabriel explains why people are so excited about Minecraft, how people are hacking Minecraft, and what the future of Minecraft is now that Microsoft has acquired it.

", + "Episodes Title": "Minecraft Programming with Gabriel Simmer", + "Episodes Uid": "SED8987195327", + "Episodes Audio File": "318edb82380c9a5ac09356749014d4d3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 259, + "Episodes ID": "16018e02-e329-11ea-91a2-a76944a6ac68", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Ringpop_edited.mp3", + "Episodes Pubdate Date": "2016-08-26", + "Episodes Summary": "

Uber has a software architecture with unique requirements. Uber does not have the firehose of user engagement data that Twitter or Facebook has, but each transaction on Uber is both high value and time-sensitive. Users are paying for transportation that they expect to be available and reasonably close by. When Uber’s system is trying to match a rider with a driver, availability is favored over consistency. It is important that the rider can always get some driver, even if it is not the best driver.
\nRingpop is a system built at Uber to provide scalable, fault-tolerant, application layer sharding. Ringpop consists of a membership protocol, consistent hashing, and forwarding capabilities. Jeff Wolski is a software engineer at Uber working in Ringpop, and he joins the show to explain how Ringpop brings coordination to distributed applications.

", + "Episodes Title": "Uber’s Ringpop with Jeff Wolski", + "Episodes Uid": "SED3722725930", + "Episodes Audio File": "60382b8a2a6303c2f9c6e3f7676c7c26.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2f4", + "Episodes ID": "0a917faa-e329-11ea-91a2-2b5f286beb4f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/productmanagement_edited.mp3", + "Episodes Pubdate Date": "2017-01-18", + "Episodes Summary": "

Product managers are responsible for guiding the design and overall functionality of software. The relationship between product managers and engineers is complimentary: a PM is viewing the product from a perspective that is closer to the customer, so the PM often has the responsibility of navigating high-level tradeoffs in the functionality of a product.

Suzie Prince is the head of product at ThoughtWorks and she joins the show to discuss how she navigates tradeoffs as a PM. We also explored communication strategies for how PMs can work productively with engineers, and the overall product development process. Full disclosure: SnapCI is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Product Management with Suzie Prince", + "Episodes Uid": "SED8957575986", + "Episodes Audio File": "74fd0d636096585ab7d2f2874416f9f9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yd", + "Episodes ID": "f6fc06d6-e328-11ea-91a2-5753ba45e0db", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ServerlessCD.mp3", + "Episodes Pubdate Date": "2017-08-07", + "Episodes Summary": "

Serverless computing reduces the cost of using the cloud. Serverless also makes it easy to scale applications. The downside: building serverless apps requires some mindset shift. Serverless functions are deployed to transient units of computation that are spun up on demand. This is in contrast to the typical model of application delivery–the deployment of an application to a server or a container that stays running until you shut it down.

Robin Weston develops large projects with AWS Lambda, and he joined me for a discussion of how to build applications for serverless environments and how to do continuous delivery with serverless functions. One big appeal for continuous delivery fans is that serverless deployments are often smaller–the user is deploying something as small as a function.

Full disclosure: ThoughtWorks GoCD is a sponsor of Software Engineering Daily.

Serverless Architectures and Continuous Delivery by Robin Weston

Robin Weston at Pipeline Conf

", + "Episodes Title": "Serverless Continuous Delivery with Robin Weston", + "Episodes Uid": "SED8487548602", + "Episodes Audio File": "f2452c19bdd0cba872379a34137fd913.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2i3", + "Episodes ID": "05e68dce-e329-11ea-91a2-1f73003bdf87", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/autoscaling_edited.mp3", + "Episodes Pubdate Date": "2017-02-28", + "Episodes Summary": "

When an application is using all of its available resources, that application needs to be scaled. Scaling an application means giving it more resources–typically servers. Autoscaling is an engineering practice where an application is automatically given more or less resources based on how healthy the application performance is at a given time.

Applications on Heroku have access to autoscaling. Heroku users don’t need to worry about provisioning new servers manually because the platform does it for them. In this episode, we explore how Heroku built autoscaling.

Andrew Gwozdziewycz [@apgwoz] is an operational experience engineer with Heroku. As he describes, autoscaling requires frequent health checks of an application. Since thousands of applications are running on Heroku, a metrics pipeline using Kafka and Cassandra supports the high volume of health check data. That data feeds into the decision process for when an application needs to scale.

Full disclosure: Heroku is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Heroku Autoscaling with Andrew Gwozdziewycz", + "Episodes Uid": "SED7173276239", + "Episodes Audio File": "ae3656d32883b5aca9abb1a8058d084e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2j9", + "Episodes ID": "045ebf80-e329-11ea-91a2-73d4353d761d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/stripeinfrastructure_fixed.mp3", + "Episodes Pubdate Date": "2017-03-16", + "Episodes Summary": "

If you are building a service that processes payments, your software architecture has a lot of requirements. Not only do you need to be highly available, consistent, and fast–you need to be PCI compliant. In this episode, we explore the infrastructure of Stripe with Evan Broder, who has been with the company for five years.

Stripe started as a small payments company catering to developers with a monolithic code base. Some of those aspects of Stripe have changed, and others have stayed the same.

In our last episode, we covered how observability works at Stripe. In this episode, we explore what is being observed–the actual infrastructure itself, and how different engineers are organized around managing the infrastructure. In tomorrow’s episode, we’ll talk to Michael Manapat, about Stripe’s machine learning pipeline for detecting and preventing fraudulent transactions.

Throughout these episodes, you will get a sense for how Stripe’s engineering culture works. We hope to do more experimental series like this in the future. Please give us feedback for what you think of the format by sending us email, joining the Slack group, or filling out our listener survey. All of these things are available on softwareengineeringdaily.com.

", + "Episodes Title": "Stripe Infrastructure with Evan Broder", + "Episodes Uid": "SED2015864435", + "Episodes Audio File": "b965dbc7dab863f299670057f3228c3a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32m", + "Episodes ID": "f65af0b6-e328-11ea-91a2-9750b799a671", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CodingVC.mp3", + "Episodes Pubdate Date": "2017-09-22", + "Episodes Summary": "

The underlying cause of failure for many startups is that the founders are afraid of discomfort. An environment where everyone is comfortable is unlikely to be an environment where personal growth and value creation is occurring.

When you are in a startup, calibrating the right amount of discomfort is often about calibrating risk.

What are your risks? Can you quantify them? Can you enumerate them? Multiplying out the probability of surviving each of those risks, then multiplying that number times the sum of the discounted future cash flows of your business will give you the expected value of your business.

Under the right circumstances, entrepreneurship has much higher expected value than a stable engineering job. The important difference is variance. Your business needs to be able to withstand the variance that bad luck can provide. And entrepreneurs themselves need to be able to withstand the variance implied by the fact that their business can completely fail and go to zero.

Leo Polovets is a partner with Susa Ventures. He worked as an early engineer at Linkedin, Google, and Factual, and he blogs at Coding VC. In this episode we talked about the proper mindset for founding a company–how to think about risk, mistakes, discomfort, and finance.

Coding VC blog

", + "Episodes Title": "The Coding VC with Leo Polovets", + "Episodes Uid": "SED5240503060", + "Episodes Audio File": "a7caacdf3cce90406942286752a82821.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3cg", + "Episodes ID": "f505dc44-e328-11ea-91a2-bb1de4bfeaa3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/dwarffortress_ad_free.mp3", + "Episodes Pubdate Date": "2017-12-29", + "Episodes Summary": "

Originally published October 22, 2015

Dwarf Fortress is a construction and management simulation computer game set in a procedurally generated fantasy world in which the player indirectly controls a group of dwarves, and attempts to construct a successful underground fortress.

Tarn Adams works on Dwarf Fortress with his brother Zach.

", + "Episodes Title": "Dwarf Fortress with Tarn Adams Holiday Repeat", + "Episodes Uid": "SED1165332166", + "Episodes Audio File": "7f5b6e75e667bf984209e176328eb38c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1hk", + "Episodes ID": "23454f0e-e329-11ea-91a2-93af65d3f9fc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/10_philosophies.mp3", + "Episodes Pubdate Date": "2016-02-13", + "Episodes Summary": "

Following the successful experiment of History of Hadoop, we are doing another Saturday experiment: an editorial podcast. Let us know your thoughts via Slack, Twitter, or email!

Our podcast errs on the side of technical rigor.

Whether the topic is distributed databases, microservices, Soylent, Uber, or Dwarf Fortress, we try to separate hype from substance, deferring the narrative to the guest. With that deference there is editorial objectivity on the part of Software Engineering Daily.

One Slack channel member said “when Software Engineering Daily’s opinions are announced, that takes time away from the guest.”

Fair enough.

However, as with any journalistic organization, we have opinions. On SE Daily, we stream objectivity and batch subjectivity.

This episode is willfully subjective. It has no guest. It is a monologue editorial inspired by Developer Tea.

Immutable laws are rare in software engineering, and when an engineer claims to have found one, that engineer is usually regarded with skepticism.

General principles are more welcome.

In this post and podcast episode, I convey some loose philosophies about modern software engineering. These are strong opinions weakly held. I welcome debate and discussion.

Software is a new field and nobody knows how to do it. If someone says you are unqualified and therefore you must do maintenance work, you should question that person. We have an upside down system where the people who are paid the least do the crappiest work. They tend to be young and naive.

This is not an axiom.

The narrative that is sold to young engineers by giant companies is the following: take your $80k/yr job, do the software maintenance which makes the company $1 million, and hate your life.

After you have spent enough time in the first tier of the intellectual strip mine, we will make you an SDE 2, where you can do slightly higher level refactoring for $150k a year, which will make the giant company $5 million. This is what is called an arbitrage.

We have an assembly line mindset left over from the industrial age. Software is more of an artisanship. Don’t believe that you are a replaceable cog. Don’t believe the one-size-fits-all interview process with whiteboarding problems. These serve to grind away your individuality and make you feel like an assembly line worker.

The planning and design process is an art, but once the requirements are in place you can proceed more deterministically. The same is true for the other quantitative activities I have taken part in–poker, music, and writing. As Michael Rosenthal and I discussed, the question of art vs. science is the same question as strategy vs. tactics.

I learned this very early on playing poker when I had to leave that career, and I had tightly coupled poker to my identity. If you make your job the same thing as who you are, then your self-worth is defined by those who are judging you in your job.

Your job is a means to service your own higher purpose.

When you take an action on your smartphone, there is latency before that action is ingested.

Servers sometimes will lie to you, but servers tend towards eventual consistency. The world works the same way. In the short term, human systems lie to us all the time, but the world tends toward eventual consistency–the truth eventually presents itself.

A decent analogy is the efficient market hypothesis: slowly efficient markets are an eventually consistent process.

The world is a distributed system–what is the consequence of this? We have to do the arduous risk and reward calculations that are mandatory for every distributed systems programmer.

Long-tail failures can and do occur.

In a distributed system, we often prioritize safety over liveness. In a distributed operating system, the programmer takes all precaution to avoid data loss. Similarly, if a real life scenario presents a small probability of giant downside risk, you should take huge precaution. If someone offers you to roll a die with 1000 sides, and if you roll a 1-999, you get $100 million, but if you roll a 1000, you get your head chopped off, the upside is capped, but the downside is not.

I can estimate how significantly $100 million will improve my life, but it is impossible to quantify how bad it is to get my head chopped off. I would almost never take that offer, because the expected value is infinitely negative.

Coming back to the consequences of living in a distributed system, there is a huge range of potential outcomes in a given transaction, and assessing these long tail, massive risks takes a lot of deep thought and calculation.

This is a quote from Peter Thiel. He argues that we should think in terms of calculus rather than statistics because if you believe the world is a lottery, then you will give yourself permission to lose.

Example: a software engineer might say “I am applying to a job with 1000 applicants, so the chances I will get the job are pretty low.” That is looking at a game of skill as a game of luck, and if you don’t optimize with lots of preparation and sleep for that interview, then it’s your own fault.

If you play poker or Magic or Dominion, it is easy to blame a loss on luck, but the best players are the ones who optimize in spite of bad luck. Personally, I like playing games under circumstances when I get unlucky because it makes for more of an interesting challenge and a better learning experience.

Luck is an idea that rescues us when we don’t do enough due diligence.

We live in a society that loves to talk about luck because it gives us an excuse when we lose. That is not to say that there isn’t luck in the world–plenty of people are unlucky. But if you are reading this, chances are you are in the luckiest .01%.

There is a long-running philosophical argument about whether or not we control our own fate. In actuality, it doesn’t really matter.

We should assume that we are in control of our own fate.

If we aren’t in control, it doesn’t change anything whether or not we assume that we are in control. But if we are in control, it would be very hazardous to our well being to assume that we are not in control.

Talk is cheap and execution is scarce.

This is why nobody cares about your ideas, they care about seeing your prototype. John Mayer said that all he had to do to become successful is finish his songs.

At Amazon, they called this “bias for action”. At Facebook, they “move fast and break things”.

That said, usually you can choose both. Long-term planning is underrated because few people take the aggressive short term actions necessary to iterate towards it. If you have never seen long-term planning bear fruits, it’s hard to see the point.

You have to figure out what to believe for yourself.

There are also lots of great people, but it is up to you to develop intuition and strong reasoning.

There is a scene from The Big Short where Mark Baum, played by Steve Carrell, is standing in front of bankers saying “the world is full of fraud, our food is fraudulent, our banking system is fraudulent, our medicine is fraudulent”, and if you look around and investigate each of these things, you do find that these systems have layers of deception and lies–software engineering is the same.

For example, if you get to a place that gives you lots of perks like free lunch or back massages, understand that they are doing that because they are underpaying you.

If you are getting $130k salary, $70k in stock options, free lunch, and free laundry, that may sound like a pretty good deal, but what does that say about how much money the company is making off of you?

According to Business Insider:

This isn’t even skewed towards how much they make off of engineers.

Software economics are unintuitive.
\n

What is crazy about software is that it takes $0 to make new copies of a commodity that only has to be written once. This contrasts with the assembly line where each new unit takes new effort and human friction to reproduce. With software, only the first unit takes significant labor to produce.

As software engineers, we have to rethink our value as workers in a marketplace with the insane leverage of software economics.

Giant tech companies can pull off this arbitrage of underpaying engineers because engineers let themselves be seduced into a set of myths.

There is a narrative of a programmer who is incapable of doing anything except programming. Some programmers talk about this with pride, saying things like “I am just an engineer, I don’t want to think about the business side of things, I don’t understand the business side of things”.

Engineers have been seduced by the industrialist’s perspective that we cannot lead ourselves, we cannot evaluate opportunity cost, and we don’t understand the market as a whole.

All of these are lies, and the world will be more efficient and utilitarian if engineers take control of their careers and start evaluating the options outside of their immediate, narrow context.

If you started in sales, you can learn to become an engineer.
\nIf you started as an engineer and don’t like it, you can become a podcaster.

You don’t need a degree–if you can do the work, you can get a job as an engineer.

In the interview with my brother Michael Rosenthal, he talked about dropping out of school and doing freelance programming, and how he has learned faster since getting out of the highly tracked education process.

In Seth Godin’s episode, he talked about the deprecated education system, and the declining worth of a degree.

Don’t let yourself be defined by your past, and the labels and messaging that society applies to you. You can take control of your life and define your future.

You should be skipping to work. We spend most of our time at work.

The job market is really good right now because our economy is being completely reshaped by software. Massive economic opportunity is being generated:

These are economic fundamentals, not spurious technical signals.

Don’t believe the ranting and raving venture capitalists arguing for lower valuations and screaming about a bubble. Don’t believe the luddite anti-technologists who sneer into their lattes.

By any logical projection, the high demand for engineers isn’t dissipating any time soon…unless the entire economy collapses in some ghastly black swan catastrophe–in which case your current job will likely vaporize anyway.

As David Heinemeier Hansson said, it is worth considering how often your job puts you in a state of flow and tranquility. If your work is stressful and entirely unpleasant, finding a new job should be a huge priority.

Thanks for reading this far. I hope this post inspires some conversation, either negative or positive and I would love to know your thoughts.

Software Engineering Daily wants to make content that is useful to engineers. Whether or not this was useful, please let us know via Slack, Twitter, or email.

", + "Episodes Title": "10 Philosophies for Engineers", + "Episodes Uid": "SED5029372861", + "Episodes Audio File": "e75e568946f63c2c18037a208d7b4b49.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5b5", + "Episodes ID": "ef73dd58-e328-11ea-91a2-07ceddc3b607", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_08_Knative.mp3", + "Episodes Pubdate Date": "2019-02-08", + "Episodes Summary": "

Infrastructure software is having a renaissance.

Cloud providers offer a wide range of deployment tools, including virtual machines, managed Kubernetes clusters, standalone container instances, and serverless functions. Kubernetes has standardized the container orchestration layer and created a thriving community. The Kubernetes community gives the cloud providers a neutral ground to collaborate on projects that benefit everyone.

The two forces of cloud providers and Kubernetes have led to massive improvements in software quality and development practices over the last few years. But one downside of the current ecosystem is that many more developers learn how to operate a Kubernetes cluster than perhaps is necessary. “Serverless” tools are at a higher level than Kubernetes, and can improve developer productivity–but a risk of using a serverless tool is the potential for lock-in, and a lack of portability.

Knative is an open-source serverless platform from Google built on top of Kubernetes. Ville Aikas is a senior staff engineer at Google who has worked at the company for eleven years. With his experience, Ville brings a rare perspective to the subjects of Kubernetes, serverless, and the infrastructure lessons of Google. Ville joins the show to discuss Knative, the motivation for building it, and the future of “serverless” infrastructure.

", + "Episodes Title": "Knative: Serverless Workloads with Ville Aikas", + "Episodes Uid": "SED3282243108", + "Episodes Audio File": "0b60f39df8b74c36359aeec508a0fad4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24w", + "Episodes ID": "16dd197c-e329-11ea-91a2-b34e61f017c2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Xeneta.mp3", + "Episodes Pubdate Date": "2016-08-16", + "Episodes Summary": "

Machine learning has become simplified. Similar to how Ruby on Rails made web development approachable, scikit-learn takes away much of the frustrating aspects of machine learning, and lets the developer focus on building functionality with high-level APIs.

Per Harald Borgen is a developer at Xeneta. He started programming fairly recently, but has already built a machine learning application that cuts down on the time his sales team has to spend qualifying leads. What I found most interesting about this episode was that machine learning gets used by a single developer to solve a simple business problem and deliver solid value. This is in contrast to how many of us think about machine learning–as an intimidating domain that requires a large team to build anything meaningful.

", + "Episodes Title": "Machine Learning for Sales with Per Harald Borgen", + "Episodes Uid": "SED4314591778", + "Episodes Audio File": "7d55f60fb53ef91bd0348fb32579ebfe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 28, + "Episodes ID": "38cc890a-e329-11ea-91a2-9f3affb763f3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/jont_typescript.mp3", + "Episodes Pubdate Date": "2015-07-29", + "Episodes Summary": "

TypeScript is a typed superset of JavaScript that compiles down to regular JavaScript. Jon Turner maintains the TypeScript package at Microsoft.

Links:

", + "Episodes Title": "TypeScript with Jon Turner", + "Episodes Uid": "SED4260508452", + "Episodes Audio File": "0cbe33a091ab6362debc505bcff9e05f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "k4", + "Episodes ID": "32d392a0-e329-11ea-91a2-1fa744da5c34", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/react_ben_alpert.mp3", + "Episodes Pubdate Date": "2015-09-17", + "Episodes Summary": "

Facebook engineering has recently produced a powerful suite of loosely coupled tools for development: React, GraphQL, Relay, React Native, and Flux Architecture.

Ben Alpert is an engineer on the React Core team at Facebook.

", + "Episodes Title": "React at Facebook with Ben Alpert", + "Episodes Uid": "SED9488046999", + "Episodes Audio File": "884c909760ac20c26a2b3dafe7f53cc7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4t", + "Episodes ID": "37ba89b8-e329-11ea-91a2-77c329c30a89", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/fpj_zookeeper.mp3", + "Episodes Pubdate Date": "2015-08-07", + "Episodes Summary": "

Flavio Junqueira is a committer and PMC of Apache ZooKeeper, and former VP of ZooKeeper.

", + "Episodes Title": "Apache ZooKeeper with Flavio Junqueira", + "Episodes Uid": "SED9577766817", + "Episodes Audio File": "4a45a0fa09daf23038c9af1c5c8cde61.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6t", + "Episodes ID": "378e05e6-e329-11ea-91a2-13c8a867bb49", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/presto_chris.mp3", + "Episodes Pubdate Date": "2015-08-08", + "Episodes Summary": "

Christopher Berner works on Presto at Facebook.

", + "Episodes Title": "Facebook Presto with Christopher Berner", + "Episodes Uid": "SED2910905540", + "Episodes Audio File": "cac0bfec0b031955cab95836d40c4d90.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "au", + "Episodes ID": "36d1f694-e329-11ea-91a2-ef1599e193f4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/memsql_nikita_2.mp3", + "Episodes Pubdate Date": "2015-08-18", + "Episodes Summary": "MemSQL with Nikita Shamgunov", + "Episodes Title": "MemSQL with Nikita Shamgunov", + "Episodes Uid": "SED2668539644", + "Episodes Audio File": "e6ae3600dda2ec278f71870de1e04e5f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "b9", + "Episodes ID": "368cf120-e329-11ea-91a2-876318a3f510", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/pipelinedb_derek.mp3", + "Episodes Pubdate Date": "2015-08-20", + "Episodes Summary": "

Derek Nelson is the CEO of PipelineDB.

", + "Episodes Title": "Streaming SQL with PipelineDB CEO Derek Nelson", + "Episodes Uid": "SED8249527094", + "Episodes Audio File": "0578f331f00a9f36d90ef02aed659e61.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "cw", + "Episodes ID": "3631fda6-e329-11ea-91a2-4b597eaf2f4f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/voltdb_rbetts.mp3", + "Episodes Pubdate Date": "2015-08-24", + "Episodes Summary": "

VoltDB provides streaming analytics with transactions.

", + "Episodes Title": "Transactions and Analytics with VoltDB’s Ryan Betts", + "Episodes Uid": "SED3440069620", + "Episodes Audio File": "3854e73526bcf03a9705be8c66726e15.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 26, + "Episodes ID": "38da29de-e329-11ea-91a2-7b86d1673c5e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/reactjs_fixed.mp3", + "Episodes Pubdate Date": "2015-07-27", + "Episodes Summary": "

React.js is a JavaScript library for building user interfaces. Facebook and Instagram maintain the open-source repository and use the technology to build front-end components.

Questions include:

", + "Episodes Title": "React.js with Sebastian Markbage and Christopher Chedeau", + "Episodes Uid": "SED7705038883", + "Episodes Audio File": "a5b16404202e9c2326916e48898dcf5b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "lz", + "Episodes ID": "322f0910-e329-11ea-91a2-43b1d8f29418", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/nancy_apptimize.mp3", + "Episodes Pubdate Date": "2015-09-22", + "Episodes Summary": "

Businesses can make changes to apps using Apptimize’s powerful and friendly editor, and free up developers’ time for more impactful work.

Nancy Hua is the Founder and CEO of Apptimize. She worked in high-frequency trading prior to starting a company.

This is the first show of Women in Tech Week, where we will discuss the inequalities women in tech face, and see what solutions may exist for this problem.

", + "Episodes Title": "Apptimize with Nancy Hua", + "Episodes Uid": "SED4273875155", + "Episodes Audio File": "a6e54c18353f51a02a34aa540f50354d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "sm", + "Episodes ID": "2f80069c-e329-11ea-91a2-4b9c966b9e37", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/derek_sivers_loud_1.mp3", + "Episodes Pubdate Date": "2015-10-14", + "Episodes Summary": "

Derek Sivers is a programmer, musician, and writer. He has created several companies and products, including CD Baby, which became the largest seller of independent music online.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

", + "Episodes Title": "Creativity and Engineering with Derek Sivers", + "Episodes Uid": "SED1303035713", + "Episodes Audio File": "29d937758b3eb7a2b5e1c0fb7bd10b8b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4q", + "Episodes ID": "37d590d2-e329-11ea-91a2-f79eac3aedab", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/eli_cloudera.mp3", + "Episodes Pubdate Date": "2015-08-02", + "Episodes Summary": "

Cloudera allows enterprises to leverage their data through its Hadoop platform. Eli Collins is the Chief Technologist at Cloudera.

Topics include:

Links:

", + "Episodes Title": "Cloudera Chief Technologist Eli Collins Discusses Streaming, Batch, Business, and Open-Source", + "Episodes Uid": "SED1958612918", + "Episodes Audio File": "b9af6b8a08fc7204707c9376d6b9c1f6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "dy", + "Episodes ID": "35273a16-e329-11ea-91a2-8f0d2093225c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/devopscafe.mp3", + "Episodes Pubdate Date": "2015-08-31", + "Episodes Summary": "

The hosts of DevOps Cafe joined Software Engineering Daily for a conversation about DevOps culture and misconceptions.

", + "Episodes Title": "Origin of DevOps with John and Damon from DevOps Cafe", + "Episodes Uid": "SED3713172850", + "Episodes Audio File": "928cae46dc96ddc675d96d8d7a756c39.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "9y", + "Episodes ID": "36dde076-e329-11ea-91a2-271485a9be10", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ethereum_aarondavis.mp3", + "Episodes Pubdate Date": "2015-08-16", + "Episodes Summary": "

Aaron Davis works on MetaMask, which brings Ethereum apps to the web browser. In this monologue episode, Aaron dives deep into the Ethereum internals, philosophy, and developer experience.

", + "Episodes Title": "Ethereum with Aaron Davis", + "Episodes Uid": "SED9579220207", + "Episodes Audio File": "92caceedf9684c8cb3571234102ac0a3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "l1", + "Episodes ID": "32706068-e329-11ea-91a2-7f56f8153662", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/brandon_tilley.mp3", + "Episodes Pubdate Date": "2015-09-20", + "Episodes Summary": "

Fluxxor is a set of tools for building JavaScript data layers using the Flux architecture. It was one of the earliest open-source implementations of Flux.

Brandon Tilley is a software engineer who works at The Minerva Project. He is the creator of Fluxxor.

", + "Episodes Title": "Fluxxor and the Flux Architecture with Brandon Tilley", + "Episodes Uid": "SED5707612521", + "Episodes Audio File": "c2d26fece9971b7dd89d1921c7e261a7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2oz", + "Episodes ID": "fc33229c-e328-11ea-91a2-0bd49c5a3bbc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/rachellaycock_edited.mp3", + "Episodes Pubdate Date": "2017-05-09", + "Episodes Summary": "

Software consultancies solve problems involving management and software engineering. A large company might hire a software consulting company to give an external opinion on software architecture, or on an organizational structure. Sometimes a consultancy is brought in to help integrate a new technology, or do a major refactoring.

Scaling a software consultancy to meet the varying demands of clients presents a unique challenge. Software companies that make money from media, or software-as-a-service, or advertising technology are primarily focused on scaling the technology. For a software consulting business, scaling and updating the team is arguably more important than any particular piece of software.

Rachel Laycock is the head of technology for ThoughtWorks North America. She joins the show to discuss how to manage and grow a large software consulting organization. It’s a great discussion of culture, technology, and how the nature of work is changing.

If you are interested in hosting a show for Software Engineering Daily, we are looking for engineers, journalists, and hackers who want to work with us on content. It is a paid opportunity. Go to softwareengineeringdaily.com/host to find out more.

The Software Engineering Daily store is now open if you want to buy a Software Engineering Daily branded t-shirt, hoodie, or mug and support the show. Let’s get on with the show. Go to softwareengineeringdaily.com/store.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Software Consulting with Rachel Laycock", + "Episodes Uid": "SED1839233773", + "Episodes Audio File": "d8f0b8b69f99b5596a7e4e0a38f9809b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 361, + "Episodes ID": "f5cb2f26-e328-11ea-91a2-7785f746e0df", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/BadMen.mp3", + "Episodes Pubdate Date": "2017-11-02", + "Episodes Summary": "

In the 1960s, advertising agencies were high-dollar creative producers. A client would come to an ad agency and pay millions of dollars for artistic messaging that would convince a consumer to buy a product.

How could you measure the success of these advertising campaigns? Maybe you could see success in the sales data. Maybe people were starting to talk about the product. Ultimately, success was defined by how satisfied the client was.

When it comes to measuring outcomes, advertising has always been a messy business.

Bob Hoffman’s long career in advertising included CEO positions at three different agencies. He helped huge brands craft their messaging, and grab consumer attention. In Bob’s world of advertising, lots of money was spent on creativity. Were the campaigns successful? That depends who you ask. In the old world of advertising, everyone acknowledged that success was subjective.

As human attention moved online, the world of advertising changed. Advertising began to move from TV and magazines to websites. Technology companies were formed to enable this new type of advertising–known as adtech. These companies claimed to bring scientific accuracy to advertising campaigns. The biggest adtech player was Google, who perfected search advertising.

If you could imagine the opposite of what Bob Hoffman built his career doing, it might look like search advertising.

Bob’s campaigns were about creating a brand’s voice, with colorful art and subtlety and ambient messaging. Advertising was about turning a brand into an entity you recognize, teaching the consumer to associate Nike with fitness, or Dove soap with clean hands, or Cheetos with cheesy, salty attitude.

Search advertising, on the other hand, is just text. You enter a search query, you are looking for black socks, and the top link that comes back is a line of text that says “cheap black socks.” Search advertising catches people who have an intent to do something. They have stated their intent by typing into a box. With search advertising, a brand might not even need a sexy, flashy creative.

The idea of intent-based advertising was expanded with retargeting. As you navigate through the internet, adtech companies are watching you, gathering data on your intent. Maybe you aren’t typing your desires explicitly into a search box–but you are clicking on articles and blog posts and tweets. With all your online interactions, adtech companies can figure out that you are looking for black socks whether you say so or not.

Money poured into adtech for very good reasons: intent-based marketing works. The shift to adtech put agencies in an uncomfortable position. If they couldn’t capture the advertising market by selling highly produced, unmeasurable creativity, they would have to make their money doing something else.

The situation was this: big brands like Procter and Gamble were buying most of their advertising through agencies. Procter and Gamble decided it wanted digital advertising. The adtech companies were the ones who knew how to produce and distribute digital advertising. Since agencies had the relationships with the big brands, and adtech companies had the technology, agencies began to partner with adtech companies.

This is actually a simplified version of what happens. Agencies subcontract advertising deals to digital agencies. A digital agency buys technology from a slew of adtech companies: some technology tracks users around the internet, some technology places bids on advertising spots that will land in front of users. Because of all the middlemen, the incentives are aligned against the brands.

Contrast this world of agencies and adtech companies with the world of Google and Facebook. They are a duopoly because they earned that position. By creating a single monolithic purchasing process, they have removed much of the risk that comes from a purchasing process stocked with middlemen.

But back to Bob Hoffman.

As money poured into adtech, user tracking, and Google, brands started to care more about metrics. When Bob met with a brand, the brand wouldn’t be asking about the cool new advertising campaign featuring a young actress drinking a Coca Cola. The brand would be asking about the click-through rate of a display advertising campaign.

Brands moved their focus to statistics, and away from creativity. And technology companies were happy to provide them with statistics. Whether those statistics were true or not is another story altogether. The industry was moving from creative BS to outright lying, and Bob decided to leave.

In today’s episode, Bob explains how the state of advertising became so problematic, and the ways in which it harms us Internet users.

We have done lots of reporting about advertising fraud for the last year, and it is a popular topic because people are often shocked to find that online advertising is inextricably linked to organized crime, surveillance, and Twitter botnets. That’s not to say that online advertising doesn’t work–it certainly does! But understanding the dark underbelly of the Internet’s cash cow is a necessary precondition to finding a solution.

To find all of our old episodes about ad fraud, you can download the Software Engineering Daily app for iOS and for Android. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Bad Men with Bob Hoffman", + "Episodes Uid": "SED4756891359", + "Episodes Audio File": "777e4790295d1ab5c7282f81a72ef150.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2q7", + "Episodes ID": "fb46e206-e328-11ea-91a2-cff016eb6bce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Firebase.mp3", + "Episodes Pubdate Date": "2017-05-17", + "Episodes Summary": "

Firebase is a backend-as-a-service. The key efficiency of a backend-as-a-service is that it enables developers to go from having a 3-tier architecture (client, server, database) to a 2-tier architecture (client, backend-as-a-service).

The team who started Firebase built it as a pivot. They had started a social network, and then they realized there wasn’t a good backend for chat tools. And so they started a chat-as-a-service tool, for people who wanted to include chat in their applications. And that led them to the fundamental realization that chat is actually representative of a broader category of real-time synchronization problems. Firebase was eventually acquired by Google.

Doug Stevenson is a senior developer advocate with Google and the host of Meet Firebase, a YouTube talk show about Firebase. It was a pleasure to sit down for a conversation with him, especially because I recently started using Firebase in my own application as a backend for real-time chat.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Firebase with Doug Stevenson", + "Episodes Uid": "SED6909069645", + "Episodes Audio File": "b40f166ad7c581c519e0694f47033378.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "59w", + "Episodes ID": "ef9cb660-e328-11ea-91a2-8ba7e9ff11e2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_29_Likewar.mp3", + "Episodes Pubdate Date": "2019-01-29", + "Episodes Summary": "

Social media has transformed our lives. It has also transformed how wars are fought. P.W. Singer’s new book “Likewar: The Weaponization of Social Media” describes the far-reaching impact of social media on the tactics and strategies used by military, business, and everyday citizens.

We have all read about stories such as Russian bots and Cambridge Analytica, but Likewar covers many more cases that are surprising and mildly frightening. From the Gaza Strip to the streets of Chicago to Taylor Swift’s Instagram feed, Likewar describes just how pervasive the effect of social media has been on warfare.

Likewar also provides historical context. For software engineers, the repurposing of social media as a weapon is disconcerting. Many of us are working on products with a social networking component. Does this make us complicit in building weapons?

We can find some reassurance in the fact that this has happened before: from the newspaper to the television, every new invention has been used repurposed for war.

In a war, a new piece of technology always presents a new vector to gain an advantage in a conflict. Because the stakes are so high in a war, there is a large incentive to find creative ways to use technology to undermine your adversaries and to help your allies.

P.W. Singer has written about robotics, cybersecurity, and modern warfare for a decade. In a previous episode, we discussed subjects like Stuxnet, drones, and social media manipulation. In today’s show, P.W. returns to talk about his book Likewar: The Weaponization of Social Media.

", + "Episodes Title": "Likewar: The Weaponization of Social Media with P.W. Singer", + "Episodes Uid": "SED7697082817", + "Episodes Audio File": "a40e87056369fab939ca91cc8122406c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "33a", + "Episodes ID": "f637c60e-e328-11ea-91a2-b70090ce0b0a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/42CodingSchool.mp3", + "Episodes Pubdate Date": "2017-10-03", + "Episodes Summary": "

42 is tuition-free developer school for students from 18-30. It was started by Xavier Niel, a French billionaire who wanted to encourage a new model of software education. 42 has campuses in France and Silicon Valley.

42 has very high standards for the students it admits, because the students that get in are not paying tuition, but they have 24/7 access to high quality computers and a beautiful campus. Unlike coding bootcamps, 42 lasts 3-5 years. Students who graduate are equipped with both computer science theory and the practical ability to see projects through on their own.

Brittany Bir is the chief operating officer of 42 Coding School in Silicon Valley.  She joins the show to talk about how 42 works and the future of programming education. At 42, the focus is on peer-to-peer learning. Students complete projects of their own choosing, and are also required to take on internships and get real world work experience.

Stay tuned at the end of the episode for Jeff Meyerson’s tip about building your brand brought to you by Indeed Prime.

If you like listening to this podcast, download the Software Engineering Daily app for iOS and Android to hear all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that. If you don’t like this episode, you can easily find something more interesting by looking at the recommendations in the app.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! The Software Engineering Daily open source community is building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend. If you are interested in contributing, check out github.com/softwareengineeringdaily–or send me an email: jeff@softwareengineeringdaily.com

", + "Episodes Title": "42 Coding School with Brittany Bir", + "Episodes Uid": "SED6430823806", + "Episodes Audio File": "7dc5386cef88cc771514a75c6cb5f78b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3fd", + "Episodes ID": "f4af8c5e-e328-11ea-91a2-53d026acab6a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_22_ContainerInstances.mp3", + "Episodes Pubdate Date": "2018-01-22", + "Episodes Summary": "

In 2011, platform-as-a-service was in its early days. It was around that time that Gabe Monroy started a container platform called Deis, with the goal of making an open source platform-as-a-service that anyone could deploy to whatever infrastructure they wanted.

Over the last six years, Gabe had a front row seat to the rise of containers, the variety of container orchestration systems, and the changing open source landscape. Every container orchestration system consists of a control plane, a data plane, and a scheduler. In the last few weeks, we have been exploring these different aspects of Kubernetes in detail.

Last year, Microsoft acquired Deis, and Gabe began working on the Azure services that are related to Kubernetes–Azure Container Service, Kubernetes Service, and Container Instances. In this episode, Gabe talks about how containerized applications are changing, and what developments might come in the next few years.

Kubernetes, functions-as-a-service, and container instances are different cloud application runtimes, with different SLAs, interfaces, and economics. Gabe provided some thoughts on how different application types might use those different runtimes. Full disclosure: Microsoft is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Container Instances with Gabe Monroy", + "Episodes Uid": "SED3798041596", + "Episodes Audio File": "5c007c7f7eac3aa377a43164f75f3646.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5j2", + "Episodes ID": "eeabbbe8-e328-11ea-91a2-bbc38a21ef0e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Data_with_Ben_Lorica.mp3", + "Episodes Pubdate Date": "2019-04-04", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Ben Lorica is the chief data scientist at O’Reilly Media and the program director of the Strata Data Conference. In his work, Ben spends time with people across the software industry, giving him broad perspective.

In the early days of the data engineering ecosystem, the Hadoop vendor wars were starting between Cloudera and Hortonworks. Strata was a neutral ground for practitioners and open source contributors to meet and share ideas about the Hadoop ecosystem. Since then, the conference has grown to encompass topics such as data science, distributed databases, streaming frameworks, and machine learning.

There are many open questions in the data world right now. What is the best path that an enterprise can take to build out a data platform? How should a software team be arranged to efficiently build machine learning models? Which distributed streaming frameworks should I use for what purpose?

Ben joins the show to discuss modern data engineering, data science, and infrastructure.

", + "Episodes Title": "Data with Ben Lorica", + "Episodes Uid": "SED2118286887", + "Episodes Audio File": "0affa834eb3f475fa303cbbf71867ff8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4q7", + "Episodes ID": "f0f48542-e328-11ea-91a2-2f8957bc8fef", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_16_OpenVSwitch.mp3", + "Episodes Pubdate Date": "2018-10-16", + "Episodes Summary": "

Virtual machines are operating system instances that run alongside each other on the same physical host. The virtual machines running on a physical host are managed by a hypervisor running on the physical host. A cluster of two physical servers could have four virtual machines running across those two physical instances. Those four virtual machines can communicate over a virtual switch.

A network switch allows packets of bytes to be routed between machines. With a physical network switch, a dedicated physical device sits in the computer network to do this routing. A virtual network switch provides this packet routing without needing a dedicated physical hardware device for routing.

Open vSwitch is a distributed virtual multilayer switch. Open vSwitch provides network switching for hardware virtualization environments. Ben Pfaff is a core contributor to Open vSwitch, and he joins the show to talk about operating system virtualization. Ben was an early employee at Nicira, a company that made significant developments in software-defined networking before being acquired by VMware in 2012.

", + "Episodes Title": "Open vSwitch: Virtual Networking with Ben Pfaff", + "Episodes Uid": "SED4023133098", + "Episodes Audio File": "3a74b3227ab9949e760a2d10c2cdba51.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "66g", + "Episodes ID": "ec6d0e5e-e328-11ea-91a2-a723ae802cb8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_12_TalkingPython.mp3", + "Episodes Pubdate Date": "2019-09-12", + "Episodes Summary": "

Python is one of the most popular programming languages in the software world.

After working with Python and developing a love for the language, Michael Kennedy started to wonder why there was not a high quality podcast dedicated to covering the community and new technologies of the Python ecosystem. Michael started Talk Python To Me as a podcast with the goal of telling stories from the world of Python. 

Today, Talk Python To Me is the most popular podcast dedicated to Python and related technologies. Subjects on the podcast include web frameworks, compilers, career development, and cloud services. One of the more recent developments in the world of Python is the prevalence of data science, which Michael also covers in great detail. Michael has also spun up a second podcast called Python Bytes, which offers timely updates to the Python community.

Michael joins the show to share his thoughts on several topics related to Python, including compilers, data science workflows, and web frameworks. Michael also gives his perspective on the world of software podcasting, which he has been doing for more than four years.

", + "Episodes Title": "Talking Python with Michael Kennedy", + "Episodes Uid": "SED4296978024", + "Episodes Audio File": "c60dd4a76bfe43230db21828f7ff6da1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ll", + "Episodes ID": "f3d978b2-e328-11ea-91a2-53270e54763d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_21_Statusim.mp3", + "Episodes Pubdate Date": "2018-03-21", + "Episodes Summary": "

To use a web application, you probably open a web browser or a mobile app. To access an Ethereum application, many people use an Ethereum browser. In previous episodes, we explored Metamask and Mist, which are Ethereum browsers for the desktop. In today’s episode, we explore Status, a mobile Ethereum browser.

Status founders Jarrad Hope and Oskar Thoren join the show to talk about the engineering of Status. How Status connects to the Ethereum blockchain, what people want from Ethereum applications, and the engineering of the Status app itself. Status is built using React Native–which is working out quite well for them.

We also talked some about the mechanics of an ICO. Status has raised $100m in their ICO for the Status Network Token. An ICO differs from raising equity in several ways. Rather than representing a direct stake in the business, a token represents a stake in the ecosystem that is being built.

Through their ICO, Status raised much more than a startup at a similar stage in company development would have–and the vesting schedule for the founders is 2 years. After two years, their stake will be liquid. This illustrates another way that the ICO can contrast with a traditional startup equity offering.

In a traditional startup, there is not a liquid open market for equity prior to the company going public. This can be good, as it forces the founders to maintain their skin in the game until they have proven the business. But it can also be bad–founders should arguably be able to take some money off of the table even if their business model is not completely worked out.

In the interview, Jarrad explained that he anticipates the open source community around Status to be contributing more to the Status app over time, because the community has a stake in the app by purchasing the Status token. I hope this is the case–it would be very cool to see more consumer-facing open source applications.

Status is a consumer facing app–and it did make me think that it is strange that there is so much open source software for building applications (think about React Native, Kubernetes, Kafka), but there are fewer consumer-facing open source apps. There’s not an open source Uber, an open source Facebook, or an open source Google. Why is that?

Maybe that’s because we are still in the days where someone has to pay for the backend compute layer. In other words–open source code is free to host, but running the actual application infrastructure still requires the owner to pay–so it makes sense that consumer applications are still developed and maintained by central actors.

With Ethereum, maybe that will change and we will see more consumer facing, open source, decentralized applications. That is certainly the world that Status.im is hoping for.

Speaking of consumer facing open source applications: check out our Software Engineering Daily apps on the iOS or Android app store. All 700 episodes of Software Engineering Daily are in the app–we’ve got tons of episodes on blockchains, business, distributed systems, and tons of other topics. If you want to become a paid subscriber to Software Engineering Daily, you can hear all of our episodes without ads–you can subscribe at softwaredaily.com. And all of the code for our apps is open source. If you are looking for an open source community to be a part of, come check out github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Status.im: Ethereum Mobile Browser with Jarrad Hope and Oskar Thoren", + "Episodes Uid": "SED6582929084", + "Episodes Audio File": "4ac7bdee9df448523290036f5f4aa0bb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5sm", + "Episodes ID": "edd1eeb8-e328-11ea-91a2-7b0625c47e7d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_04_KubernetesInfrastructureTimHockin.mp3", + "Episodes Pubdate Date": "2019-06-04", + "Episodes Summary": "

Kubernetes has evolved from a nascent project within Google to a thriving ecosystem of cloud providers, open source projects, and engineers.

Tim Hockin is a principal software engineer who has been with Google for 15 years. Tim joins the show to talk about the early days of the Kubernetes projects, and the engineering efforts that are under way five years into the project.

At KubeCon EU 2019, two of the prevalent subjects of discussion were service mesh and serverless–particularly the Knative project. Tim gave his perspective for how projects that are adjacent to Kubernetes are developed within the community.

", + "Episodes Title": "Kubernetes Development with Tim Hockin", + "Episodes Uid": "SED9811227802", + "Episodes Audio File": "f4a7ef6b6e0a092ad9328adc22adee3a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "35z", + "Episodes ID": "f5e395fc-e328-11ea-91a2-6ff1f744a37b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/AnalyseAsia.mp3", + "Episodes Pubdate Date": "2017-10-27", + "Episodes Summary": "

In America, the tech companies we focus on are commonly known as FAANG: Facebook, Amazon, Apple, Netflix, Google. We all know what these companies do because they impact our daily lives. In Asia, there are three giant tech companies that have similar scale: Baidu, Alibaba, and Tencent, otherwise known as BAT.

Technology within a location is shaped by the pressures of that location. You might think we live in a global society, but tech in Asia is dramatically different than it is in America. Differences in culture lead to differences in product development.

In China, a different political system contributed to more rapid adoption of online payments. Because there is more payment data, people can be given loans more efficiently. Less of the population is “unbanked.” Online payments are mostly handled by WeChat, a social networking product from Tencent, and Alibaba, an ecommerce giant. If you live in the West, imagine that Facebook and Amazon handled most of your payments for everything. You would have a different relationship with those companies.

Bernard Leong is the host of Analyse Asia, a podcast about Asian developments in technology in business. After studying materials science in Singapore and theoretical physics at Cambridge, he made his way into business and journalism, and developed an interest in the Singularity–a subject that few people took seriously until recently (one topic we explored in this show is Masayoshi Son, the Japanese tycoon who wants to invest nearly a trillion dollars into technology companies; Masayoshi believes firmly that the Singularity is coming).

Shenzhen: The Silicon Valley of Hardware (Full Documentary) | Future Cities | WIRED

In the Plex by Steven Levy

The Hidden Forces Behind Toutiao: China’s Content King

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Analyse Asia with Bernard Leong", + "Episodes Uid": "SED2385309187", + "Episodes Audio File": "8a608bc49b8902a8341c775427317432.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3cl", + "Episodes ID": "f5009824-e328-11ea-91a2-9b4d0834dad4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CloudFoundry.mp3", + "Episodes Pubdate Date": "2018-01-03", + "Episodes Summary": "

Cloud Foundry is an open-source platform as a service for deploying and managing web applications. Cloud Foundry is widely used by enterprises who are running applications that are built using Spring, a popular web framework for Java applications, but developers also use Cloud Foundry to manage apps built in Ruby, Node and any other programming language. Cloud Foundry includes routing, message brokering, service discovery, authentication and other application level tooling for building and managing a distributed system. Some of the standard tooling in Cloud Foundry was adopted from Netflix open-source projects, such as Hystrix, which is the circuit breaker system; and Eureka, which is the service discovery server and client.

When a developer deploys their application to Cloud Foundry, the details of what is going on are mostly abstracted away, which is by design. When you’re trying to ship code and iterate quickly for your organization, you don’t want to think about how your application image is being deployed to underlying infrastructure. You don’t want to think about whether you’re deploying a container or a VM, but if you use Cloud Foundry enough, you might have become curious about how Cloud Foundry schedules and runs application code.

BOSH is a component of Cloud Foundry that sits between the infrastructure layer and the application layer. Cloud Foundry can be deployed to any cloud provider because of BOSH’s well-defined interface. BOSH has the abstraction of a stem cell, which is a versioned operating system image wrapped in packaging for whatever infrastructure as a service is running underneath. With BOSH, whenever a VM gets deployed no your underlying infrastructure, that VM gets a BOSH agent. The agent communicates with the centralized component of BOSH called the director. This role of director is the leader of the distributed system.

Rupa Nandi is a director of engineering at Pivotal where she works on Cloud Foundry. In this episode we talked about scheduling an infrastructure, the relationship between Spring and Cloud Foundry and the impact of Kubernetes, which Cloud Foundry has integrated with so that users can run Kubernetes workloads on Cloud Foundry.

I interviewed Rupa at SpringOne Platform, a conference that is organized by Pivotal who, full disclosure, is a sponsor of Software Engineering Daily, and this week’s episode are all conversations from that conference. Whether you like this format or don’t like this format, I would love to get your feedback. We have some big developments coming for Software Engineering Daily in 2018 and we want to have a closer dialogue with the listeners. Please send me an email, jeff@softwareengineeringdaily.com or join our Slack channel. We really want to know what you’re thinking and what your feedback is, what you would like to hear more about, what you’d like to hear less about, who you are.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cloud Foundry with Rupa Nandi", + "Episodes Uid": "SED2478899841", + "Episodes Audio File": "3dce646344a39d7cbc3fe27431cdec79.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4td", + "Episodes ID": "f0cf9ea8-e328-11ea-91a2-6bfa390df59f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_26_BloxRoute.mp3", + "Episodes Pubdate Date": "2018-10-26", + "Episodes Summary": "

Cryptocurrencies are not very usable today. The main use cases for cryptocurrencies today are store of value (somewhat like gold) and speculation. One reason that the use cases are so narrow is the problem of scalability. Cryptocurrencies have several scalability bottlenecks.

Think about the Internet in 1994. The consumer sitting at home with a dial-up modem was bottlenecked on bandwidth between their home and the broader network. The physical network connections between our homes and Internet company servers were much lower bandwidth than we have today. The servers at companies such as AOL were slow and expensive.

The Internet scalability problems were incrementally solved, one by one. Different solutions to different scalability problems emerged in an iterative, frothy process. Then, all of a sudden, you are sitting on an airplane watching YouTube videos on a smartphone.

Watching YouTube videos on a smartphone would have sounded unbelievable to someone in 1994, much like sending someone a penny across the Internet is unbelievable today. If you want to send a penny across the world today, you will probably have to pay several dollars worth of transaction costs.

Someday, you will be able to use cryptocurrency to send 1 penny to someone in another continent halfway around the world. The transaction fee you pay will be a fraction of a penny. This removal of financial friction due to transaction costs will change global economics.

What stands between modern cryptocurrencies and that beautiful future world of micropayments? A large set of scalability problems, similar to the scalability problems of the consumer Internet in 1994. In today’s show, we focus on one particular issue of scalability: block propagation time.

Cryptocurrency transactions are verified by miners. On the Bitcoin blockchain, a set of transactions gets verified roughly every 10 minutes. These transactions represent a “block” on the blockchain. The miner who solves the cryptographic puzzle associated with the transactions in that block receives payment in the form of a block reward and the transaction fees that are associated with those transactions.

When you issue a transaction to the Bitcoin network, your transaction sits in the mempool, a list of pending transactions that have not been confirmed by the mining process yet. Miners around the world are simultaneously competing with each other to find a solution to a pending set of transactions sitting in this mempool. When a miner includes your transaction in a block, and the miner discovers a solution to that block, your transaction will probably be accepted into the blockchain.

The reason that your transaction is not guaranteed to be accepted is due to a time period known as “block propagation time”. Block propagation time is the time it takes for a confirmed block of transactions to make its way through a blockchain network. If two blocks are solved at nearly the same time by different miners, the winner of the current block reward will be the miner whose block manages to propagate through the network the fastest.

BloxRoute Labs is a company that is developing a blockchain distribution network (BDN). Much like a CDN pushes media files out to the edges of the web to make them faster to access, a BDN pushes out information to miners in the network. Of course, this means that the BDN could potentially be centralized infrastructure. In order to make the BDN effectively decentralized and trustworthy, BloxRoute claims to have a provably trustable network protocol, to go with its token-based incentive system that keeps its goals aligned with that of the larger blockchain world.

Aleksander Kuzmanovic is the founder of BloxRoute Labs, as well as a professor of computer science at Northwestern University. His co-founders of BloxRoute include former guests of the show Emin Gun Sirer and Soumya Basu. The BloxRoute founders have a strong theoretical background and a great reputation in the cryptocurrency community, unlike the vast majority of founders who have issued a token.

As we have heard in previous episodes, most of the founders of companies that issue tokens cannot give a good explanation for why their protocol needs a token. Tokens are a great idea that have mostly been applied as a mechanism to get rich quickly. However, BloxRoute has a credible explanation for their token, and I asked some very pointed questions to Aleksander in today’s episode to try to vet the project for legitimacy, and his reasoning made sense.

", + "Episodes Title": "Blockchain Distribution Network with Aleksandar Kuzmanovic", + "Episodes Uid": "SED2900002600", + "Episodes Audio File": "4859ee4280630ee03cc63737509f9ba4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "46c", + "Episodes ID": "f23a5bb6-e328-11ea-91a2-d7084171cffa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_16_Density.mp3", + "Episodes Pubdate Date": "2018-07-16", + "Episodes Summary": "

If you operate a restaurant, you want to know how many people are inside your restaurant at any given time. You also want to be able to know your occupancy if you operate a movie theater, coffee shop, or apparel store.

Knowing how many people are in your building can answer several business-related questions. Do you need to unlock an additional entrance? Should you open another store? Do you really need a building this big?

This might sound like a simple question, but how do you solve the problem of counting people inside of a building?

A naive approach to counting people is to use video cameras and count the number of people entering and exiting the building. Machine learning algorithms are good at classifying humans. But the downside of this is that you have to put cameras anywhere you want a people-counter. There are many situations where you would want to count the number of people where a camera is not acceptable. What if you wanted to count people in a privacy preserving way? What if you wanted to obscure any identifiable traits of a person that you were counting?

Density is a device for counting people. It sits above a doorway and counts the people who are entering or exiting the building. Andrew Farah is the CEO at Density, and in today’s episode he explains why the problem of counting people is harder than it sounds, and how the Density people counter functions.

", + "Episodes Title": "Counting People with Andrew Farah", + "Episodes Uid": "SED5890092606", + "Episodes Audio File": "d57263cb766224e27d16699c96bd5f48.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5d1", + "Episodes ID": "ef4b0e50-e328-11ea-91a2-5728d319290a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_21_PlanetScaleData.mp3", + "Episodes Pubdate Date": "2019-02-21", + "Episodes Summary": "

In the early days of YouTube, there were scalability problems with the MySQL database that hosted the data model for all of YouTube’s videos. The state of the art solution to scaling MySQL at the time was known as “application-level sharding.”

To scale a database using application-level sharding, you break up the database into shards–disjoint regions of data. When you want to query the database, you need know which shard to query. In your application code, you have to issue the query to a specific shard.

The solution of application-level sharding does scale your database. But the downside is that every application that interfaces with the database now has to include code that is aware of the sharding schema.

If you are an application engineer, you don’t want to have to worry about the way that the database is sharded, because it adds significant complexity to your code. The engineers at YouTube decided to fix this problem with a project called Vitess. Vitess abstracts away the details of sharding by orchestrating reads and writes across the distributed database.

In a previous episode, we covered the architecture, read and write path, and the story of Vitess in detail. In today’s episode, Jiten Vaidya and Dan Kozlowski of PlanetScale Data join the show to give their perspective on MySQL scalability, and their work taking Vitess to market as a solution to scaling relational databases.

", + "Episodes Title": "PlanetScale: Sharded Database Management with Jiten Vaidya and Dan Kozlowski", + "Episodes Uid": "SED8727175723", + "Episodes Audio File": "ce4cd98df20eab5b0d9a0fce7dba258d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5qk", + "Episodes ID": "ee08c5e6-e328-11ea-91a2-e32aa9ce996e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_17_FBMikeVernal.mp3", + "Episodes Pubdate Date": "2019-05-17", + "Episodes Summary": "

Facebook’s strategy is shaped by long term goals, short term requirements, and the available resources of the company.

Long term goals are necessary for thinking through big decisions such as acquisitions, hardware product investments, and open source software ecosystems. To implement long term goals, Facebook needs to communicate the vision of the company and foster an internal culture that supports that vision.

Short term requirements can affect how the company is thinking on a more immediate time horizon.

When Facebook realized the importance of mobile computing, the mentality in the company quickly shifted from looking at mobile as a tax on engineering resources to a long-term source of business value. When Google started to work on Google+, Facebook engineers focused their resources on the potential competitive threat.

Facebook’s strategy is implemented by the engineers, product managers, and other employees of the company. Facebook is unique in its ability to allow those employees to self-assemble into work that is meaningful to the individuals as well as to the company.

As the long term goals and short term requirements of Facebook change over time, company resources are shifted to focus the company on the correct set of priorities. Some of those priorities might be speculative investments in new technologies. Other priorities might include doubling down on areas of the company that are showing promise.

Mike Vernal worked as a VP of product and engineering at Facebook for 8 years. He left the company in 2016 and joined Sequoia Capital, where he now works as a partner. In his time at Facebook, he helped architect and implement strategies relating to product direction and engineering.

Mike joins the show for a discussion about his time at Facebook and the strategic lessons that he learned from his time at the company.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Facebook Strategy with Mike Vernal", + "Episodes Uid": "SED1466447897", + "Episodes Audio File": "738a20e90fe3066073b77edb8b76a69f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4rs", + "Episodes ID": "f0e20c96-e328-11ea-91a2-7380f16bee44", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_22_GoogleJavascript.mp3", + "Episodes Pubdate Date": "2018-10-22", + "Episodes Summary": "

Google Search is a highly interactive JavaScript application. As you enter a query, results are being automatically suggested to you before you even finish typing. When you press enter, some of your search results may be widgets that represent the weather, the price of a stock, a recipe for green bean soup, or a language translation for a phrase. These complex frontend components are loading dynamically–the Google Search application cannot prefetch every single possible widget that you might ask for–but the results do load very quickly.

Google has many other examples of advanced JavaScript engineering. The company is mostly known for backend engineering inventions like MapReduce, TensorFlow, Dremel, and Spanner. To turn these backend tools into user facing products, Google develops its own JavaScript frameworks and infrastructure to deliver information from the backend to the frontend.

“Backend” and “frontend” are not precise terms. At Google, there are so many layers of infrastructure between a user and the data center. If you are an engineer working on a service at Google, you probably have several “frontends” and “backends” on either side of you.

Malte Ubl is a senior staff engineer at Google. He’s heavily involved in Google’s JavaScript infrastructure, and has written about managing large JavaScript applications in detail. He also works on AMP, an open-source project for delivering web pages in a fast, performant format. He joins the show to describe Google’s history with JavaScript frameworks, the process of building frontends and middleware to deliver JavaScript applications, and the engineering behind AMP. There are criticisms of AMP, but some of them misunderstand how the AMP technology actually works.  AMP allows pages to be cached, prefetched, and served to a user more quickly. AMP does not necessarily centralize pages around being served from Google Search. A good example of AMP speeding up pages outside of Google is reddit.

We recently launched a new podcast: Fintech Daily! Fintech Daily is about payments, cryptocurrencies, trading, and the intersection between finance and technology. You can find it on fintechdaily.co or Apple and Google podcasts. We are looking for other hosts who want to participate. If you are interested in becoming a host, send us an email: host@fintechdaily.co

", + "Episodes Title": "Google JavaScript with Malte Ubl", + "Episodes Uid": "SED5795499315", + "Episodes Audio File": "b795ae9a0f063442d81415d26f168e8b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4pa", + "Episodes ID": "f0fe1954-e328-11ea-91a2-37caac1a0592", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_11_DevOps_Msft.mp3", + "Episodes Pubdate Date": "2018-10-12", + "Episodes Summary": "

The Windows operating system is one of the most widely used pieces of software in history. Windows was started before there was any alternative to a monolithic codebase, because Microsoft was building software before the Internet was widely used by consumers. Networked computers gave rise to web applications, and software engineers began to rethink how to build everything.

Software development got reimagined with agile. Monolithic codebases got broken up into service-oriented architecture. Instead of going to a store to buy a box with software in it, users downloaded software from the Internet, and that software was regularly updated.

Software that is regularly updated needs to be regularly tested. Instead of a single round of testing for every round of boxed software that was shipped to a store, continuous testing and delivery gradually became the norm. The process of releasing and operating software became its own set of engineering challenges–which was tackled by the “operations” or “sys admin” team at a software company.

Now there were two different sets of engineers–those who were developing the software and those who were operating the software. The incentives of these two types of engineers were not completely aligned. The software developers wanted to build software quickly and release new features. The operators wanted things to release software slowly, because if something broke then the operators were the first line of defense for fixing it.

These problems between development and operations gave rise to the “DevOps” movement, in which developers and operations started working more closely together and sharing responsibilities. Incentives became aligned, and new types of software was created to facilitate more harmonious relationships between developers and operations–for example, continuous delivery pipelines.

Today, most enterprises are still undergoing a transformation from monolithic software release cycles to continuous delivery. This is often referred to as a “DevOps Transformation”. A DevOps Transformation requires the entire organization to reorient itself around faster software release cycles. This can be a painful process, and we have covered it in many past shows. Hearing case studies from enterprises can be helpful for figuring out how to reorient your own enterprise.

Microsoft is a useful case study in shifting towards DevOps. Windows is perhaps the biggest monolithic codebase in history. The fact that Microsoft could rearchitect Windows to be easier to work with should provide some reassurance to other enterprises who are currently undergoing their own migrations.

Martin Woodward has been at Microsoft for 13 years and he joins the show to talk about how software delivery within the company has evolved. We discussed the move from boxed software delivery to delivery via the cloud, and focused on a few specific, longstanding products such as Windows. Martin has been part of the effort to build Azure DevOps, which is a product that offers similar tools to the ones Microsoft built internally for DevOps as a service. We also talk about the specific difficulties that enterprises often have when moving toward DevOps. Full disclosure: Microsoft is a sponsor of Software Engineering Daily.

", + "Episodes Title": "DevOps at Microsoft with Martin Woodward", + "Episodes Uid": "SED5865335911", + "Episodes Audio File": "e230238651187fd9d5afef6aa9b40da3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3gy", + "Episodes ID": "f46e9834-e328-11ea-91a2-ef930d0fa493", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_07_MattLeising.mp3", + "Episodes Pubdate Date": "2018-02-07", + "Episodes Summary": "

Your friends from college are asking you how to buy Bitcoin. Your mom is emailing you articles about the benefits of decentralized peer-to-peer networks. Your shoe shiner is telling you to buy XRP.

It is 2018, and cryptocurrencies have become a daily part of news headlines. The general public may not understand how this technology works, but everyone knows that changes are on the horizon. At some point in the future, our financial and computing systems will be deeply integrated with the cryptoeconomy.

We all remember the dot com boom. We know that some people got fantastically rich during that period through speculation. We think–maybe this is our chance to make money.

If you read reddit, or almost any news site, you will see stories of obscene wealth intertwine with pseudoscientific discussions of how a new cryptocurrency is going to change the world. What is fact and what is fiction? How far are we from a beautiful future, with frictionless micropayments?

Matt Leising is a journalist at Bloomberg who has covered financial markets for 15 years. Today, his reporting has been completely engulfed by cryptocurrencies. There are so many dramatic stories, it’s hard to pick what to focus on.

Today, we discuss two topics he has covered recently: Ripple and Tether.

Ripple is a company that makes enterprise blockchain solutions for global payments. That sounds like the future, and it is no surprise that people would want to buy into Ripple if possible. Ripple has been around for 7 years, and they have a strong team, and relationships with major financial institutions.

One of Ripple’s early projects was a currency called XRP.  The goal of XRP was to make a fast, scalable digital asset that would facilitate currency exchange among banks. We covered Ripple and XRP in previous episodes with David Schwartz and Greg Kidd.

XRP remains in circulation, but Ripple the company has shifted development resources away from XRP, and towards RippleNet, which seeks to replace the aging SWIFT code system for banks. Today, XRP is being experimented with by several money transfer companies, but the digital currency is not widely used for anything–well, other than speculation.

In the tremendous cryptocoin bull run of early 2018, XRP shot up as sharply as almost any other coin. In an article about Ripple, Matt Leising tried to get to the root explanation for why this occurred. Was it a sudden market recognition of some long term value of XRP? Was it a stampeding herd of people who did not know the state of XRP? Was it a pump and dump?

A few days after publishing his article about Ripple, Matt wrote about Tether. Tether purports to be a “stablecoin”–a digital currency which is pegged to the value of something less volatile. Stablecoins are useful in that they can reduce friction of exchange between tokens. Without a stablecoin, you might have to transfer from one cryptocurrency to USD, which probably involves the US banking system.

There’s a good discussion of stablecoins in our episode with Vlad Zamfir and Haseeb Qureshi on cryptoeconomics.

If you can use Tether instead of USD, you have less transactional friction. Perhaps you can escape the onerous tax consequences of day trading cryptocurrencies. Tether claims to have $1 USD in reserve for every 1 Tether in circulation.

So if you wanted to cash out Tether for USD, you should theoretically be able to do that–except that Tether seems to have no connection to any banks. And Tether has severed its ties with auditing agencies that it was working with.

There is $2.3B of Tether in circulation. That is a small fraction of the overall trading volume of cryptocurrencies. But it is unknown how much the current crypto bubble is propped up by the functionality of Tether–the ability to seamlessly move between cryptocurrencies without going into USD. As long as the market believes in Tether (and today it is indeed at $.999014) in valuation, this stablecoin mystique will persist, and market friction will continue to be smoothed out by that belief.

This was Matt’s second appearance on the show, and it was a blast to have him back on. In his last episode, he discussed the infamous DAO hack, which led to an Ethereum fork. To find that episode as well as links to learn more about the topics described in the show, download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Tether, Ripple, and Blockchain Reporting with Matt Leising", + "Episodes Uid": "SED6043180350", + "Episodes Audio File": "ef69b43271d9e4bb66883ae0647ca25b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2mn", + "Episodes ID": "fef9f7bc-e328-11ea-91a2-672b55ff49af", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RoundtablewithCalebandCourtland.mp3", + "Episodes Pubdate Date": "2017-04-24", + "Episodes Summary": "

Software Engineering Daily examines the world through the lens of software engineering. In most episodes, an expert in a particular topic joins the show as a guest, and we go into deep technical detail. Occasionally we like to do episodes where we survey a collection of topics.

In today’s topic roundtable, Caleb Meredith and Courtland Allen join me for a discussion of several questions: would it make sense for Facebook to build an operating system? Does online advertising work? How can you work productively on an engineering company with your brother as a co-founder?

Courtland is the founder of IndieHackers.com, which was recently acquired by Stripe. Caleb Meredith is the lead JavaScript correspondent of Software Engineering Daily. It was a blast talking to both of them, and we plan to do more round table episodes in the future.

We would love to get your feedback on Software Engineering Daily. Please fill out the listener survey, available on softwareengineeringdaily.com/survey. Also–Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to download the Topic Roundtable transcript.

", + "Episodes Title": "Topic Roundtable with Courtland Allen and Caleb Meredith", + "Episodes Uid": "SED3868271285", + "Episodes Audio File": "fb2c69c3967e8cab05a75d9573e70819.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ip", + "Episodes ID": "0514e0bc-e329-11ea-91a2-bfef7ce45104", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/aiwithrumman_edited_1.mp3", + "Episodes Pubdate Date": "2017-03-09", + "Episodes Summary": "

Machine learning has improved both in tools and accessibility. Frameworks like TensorFlow create the right abstractions for developers to work efficiently. Educational programs like Metis and Insight Data Science provide a place for developers to learn these tools. As a result, artificial intelligence is becoming easier to develop and more widespread.

Rumman Chowdhury works on artificial intelligence at Accenture. Before her current role, she taught data science at Metis. In this episode, we talk about the current state of artificial intelligence, from the tools available to the long term implications–such as the robot tax recently proposed by Bill Gates.

", + "Episodes Title": "Artificial Intelligence Implications with Rumman Chowdhury", + "Episodes Uid": "SED3211159531", + "Episodes Audio File": "0239051950dea0b0a1765a35db264bf2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5nr", + "Episodes ID": "ee45557e-e328-11ea-91a2-2fcf21516d71", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_01_SoftwareGrowthwithGregKogan.mp3", + "Episodes Pubdate Date": "2019-05-01", + "Episodes Summary": "

Growing a software business requires an understanding of engineering, sales, and marketing.

As we learn software engineering, we also pick up some knowledge about how a business should operate. We know that there are customers, and that our product needs to be scalable to serve more customers. We know that some features are more important than others, and so we focus on building the features that matter the most.

But unless we make a deliberate focus, engineers do not learn how to sell and market a software product.

Learning how to sell and market software is an important skill to develop. It allows a software engineer to be self-sufficient. If you already know how to write software, sales and marketing are actually the only other pieces you need to be an “entrepreneur”. And the basics of sales and marketing are often easier and more fun to learn than the first painful days of learning basic programming.

Greg Kogan is an engineer who has shifted his focus to working as a consultant for companies that are trying to go to market with a technical product. Greg has helped grow companies such as Netlify, Scalyr, and Domino Data Lab. Much of his work is around products targeted toward developers.

Greg joins the show to describe his methodical approach to selling and marketing software.

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Software Growth with Greg Kogan", + "Episodes Uid": "SED2538603860", + "Episodes Audio File": "fc911fd278c449393da97a383ffc09db.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5sn", + "Episodes ID": "edcd8e36-e328-11ea-91a2-cfef2b530cce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_05_MulticloudFuturewithBassamTabbara.mp3", + "Episodes Pubdate Date": "2019-06-05", + "Episodes Summary": "

Each cloud provider offers a different set of services which are not always compatible with each other. What are the challenges of building an application that interoperates with multiple different clouds?

The first issue is API compatibility.

Most cloud providers have a managed SQL offering, a bucket storage system, and server abstractions like virtual machines and containers. But these tools might have different APIs on each cloud. The code that you wrote to save your application data to Amazon S3 might have to be rewritten if you decide to switch your bucket storage to a different provider.

Another issue that interferes with cloud interoperability is the degree of integration on a particular cloud. If I build my application for AWS, I might be heavily integrated with Amazon’s Identity and Access Management policy system and AWS logging. Each cloud provider makes it particularly easy to connect to their integrated solutions.

There is also the problem of services on one cloud that simply do not map to a service on any other cloud. Google Cloud Bigtable does not have an equivalent service on Amazon. Microsoft CosmosDB does not have an equivalent service on Digital Ocean.

As developers, this irritates us. We want to be able to deploy our application to any cloud. We want to be able to move applications easily from one cloud to another. And we want to mix tools from different clouds together as easily as we import a library.

Bassam Tabbara is the CEO of Upbound, a company focused on making multicloud applications easier to deploy and operate. I spoke to Bassam at KubeCon EU 2019, and he described the problems of multicloud deployments and the opportunities for the cloud native ecosystem to become more cross-compatible.

", + "Episodes Title": "Multicloud Future with Bassam Tabbara", + "Episodes Uid": "SED7132506218", + "Episodes Audio File": "5db00c8c45f89cf332d3c1ba33a43c1e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "38p", + "Episodes ID": "f5845ae2-e328-11ea-91a2-6b13278a6179", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/LoadBalancingatScale.mp3", + "Episodes Pubdate Date": "2017-11-22", + "Episodes Summary": "

Facebook serves interactive content to billions of users. Google serves query requests on the world’s biggest search engine. Uber handles a significant percentage of the transportation within the United States. These services are handling radically different types of traffic, but many of the techniques they use to balance loads are similar.

Vivek Panyam is an engineer with Uber, and he previously interned at Google and Facebook. In a popular blog post about load balancing at scale, he described how a large company scales up a popular service. The methods for scaling up load balancing are simple, but effective–and they help to illustrate how load balancing works at different layers of the networking stack.

Let’s say you have a simple service where a user makes a request, and your service sends them a response with a cat picture. Your service starts to get popular, and begins timing out and failing to send a response to users.

When your service starts to get overwhelmed, you can scale up load by creating another service instance that is a copy of your cat picture service. Now you have two service instances, and you can use a layer 7 load balancer to route traffic evenly between those two service instances. You can keep adding service instances as the load scales and have the load distributed among those new instances.

Eventually, your L7 load balancer is handling so much traffic itself that you can’t put any more service instances in front of it. So you have to set up another L7 load balancer, and put an L4 load balancer in front of those L7 load balancers. You can scale up that tier of L7 load balancers, each of which is balancing traffic across a set of your service instances. But eventually, even your L4 load balancer gets overwhelmed with requests for cat pictures. You have to set up another tier, this time with L3 load balancing…

In this episode, Vivek gives a clear description for how load balancing works. We also review the 7 networking layers before discussing why there are different types of load balancers associated with the different networking layers.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Load Balancing at Scale with Vivek Panyam", + "Episodes Uid": "SED6897431011", + "Episodes Audio File": "a2305db8faa86f6c85c7da30122ff730.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3md", + "Episodes ID": "f3b04924-e328-11ea-91a2-bf0f845f0146", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_02_ZcashSeanBowe.mp3", + "Episodes Pubdate Date": "2018-04-02", + "Episodes Summary": "

Zcash is a payment and consensus system that allows users to transfer money to each other with strong guarantees of privacy. Zcash implements the same core features of Bitcoin, with the added functionality of shielded payments.

Shielded payments are private, and they are enabled by a novel cryptographic technique called zk-SNARKS: zero knowledge succinct non-interactive argument of knowledge. A zk-SNARK allows for the proof that a certain piece of information is valid without revealing any information other than the validity of that information itself.

Before you listen to this episode, it might be useful to go back to our previous episode about Zcash with Nathan Wilcox, in which he gives an overview of the technology. This episode is a deeper dive into how Zcash transactions work, and why zk-SNARKS are important.

We would love for you to fill out our listener survey at softwareengineeringdaily.com/survey. This will help us decide what other content to focus on.

Of course–you can also send me an email at any time, jeff@softwaredaily.com. And in the meantime, if you are completely sick of cryptocurrencies, check out our back catalog of episodes at softwaredaily.com, or by downloading our apps, which have all of our episodes including our Greatest Hits, which is a curated set of the most popular shows. The apps will soon have offline downloads and bookmarking.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Zcash Design with Sean Bowe", + "Episodes Uid": "SED8477142559", + "Episodes Audio File": "98d025475308e0b5702e0ac29aa8eeab.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yk", + "Episodes ID": "f6d00f7c-e328-11ea-91a2-43f9484fc634", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ErrorDiagnosis.mp3", + "Episodes Pubdate Date": "2017-08-18", + "Episodes Summary": "

When a user experiences an error in an application, the engineers who are building that application need to find out why that error occurred. The root cause of that error may be on the user’s device, or within a piece of server-side logic, or hidden behind a black box API. To fix a complex error, we need a stack trace of contextual information so that we can correlate events across all layers of an application.

James Smith is the CEO of Bugsnag, a company that makes crash reporting and error tracking software. In this episode, he describes how to diagnose errors in modern applications. He also explains how the company functions and how Bugsnag itself is built. The product consumes and stores millions of events which makes for a good discussion of software architecture. Full disclosure: Bugsnag is a sponsor of SE Daily.

", + "Episodes Title": "Error Diagnosis with James Smith", + "Episodes Uid": "SED8491863234", + "Episodes Audio File": "11de15b8274d164ee971bdb6368542b8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yn", + "Episodes ID": "f6c74612-e328-11ea-91a2-4b1f1e68c239", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SimilaritySearch.mp3", + "Episodes Pubdate Date": "2017-08-22", + "Episodes Summary": "

Querying a search index for objects similar to a given object is a common problem. A user who has just read a great news article might want to read articles similar to it. A user who has just taken a picture of a dog might want to search for dog photos similar to it. In both of these cases, the query object is turned into a vector and compared to the vectors representing the objects in the search index.

Facebook contains a lot of news articles and a lot of dog pictures. How do you index and query all that information efficiently? Much of that data is unlabeled. How can you use deep learning to classify entities and add more richness to the vectors?

Jeff Johnson is a research engineer at Facebook. He joins the show to discuss how similarity search works at scale, including how to represent that data and the tradeoffs of this kind of search engine across speed, memory usage, and accuracy.

Notes: Jeff’s blog post about similarity search

", + "Episodes Title": "Similarity Search with Jeff Johnson", + "Episodes Uid": "SED1586797423", + "Episodes Audio File": "1a64c1871b9ff755cd2644a30995456a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "29y", + "Episodes ID": "115dc78a-e329-11ea-91a2-7b5dd50e0243", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/antifraud_edited.mp3", + "Episodes Pubdate Date": "2016-11-10", + "Episodes Summary": "

When Facebook acquired Instagram, one of the first systems Instagram plugged into was Facebook’s internal spam and fraud prevention system. Pete Hunt was the first Facebook engineer to join the Instagram team. When he joined, the big problems at Instagram were around fake accounts, harassment, and large volumes of spammy comments.

After seeing the internal Facebook spam prevention tools clean up Instagram, Pete decided to start a company to build products that would allow this type of spam and fraud prevention as a service.

Smyte provides protection against bad actors on the Internet. Complex marketplaces like Tilt, Meetup, and TaskRabbit plug into Smyte to filter their transactions for suspicious behavior. In this episode, we talk about how this type of behavior manifests, and the event-driven software architecture that the team at Smyte has built.

", + "Episodes Title": "Fraud Prevention with Pete Hunt", + "Episodes Uid": "SED8963580509", + "Episodes Audio File": "d215d87e3251a8a2b4951e369c187b3e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 553, + "Episodes ID": "f0039592-e328-11ea-91a2-0bf5ebd24c49", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_01_AnatomyofNext.mp3", + "Episodes Pubdate Date": "2018-12-26", + "Episodes Summary": "

Originally posted on 1 May 2018.

Technology is pushing us rapidly toward a future that is impossible to forecast. We try to imagine what that future might look like, and we can’t help having our predictions shaped by the media we have consumed.

1984, Terminator, Gattaca, Ex Machina, Black Mirror–all of these stories present a dystopian future. But if you look around the world, the most successful technologists are mostly guided by a sense of optimism. Technologists themselves are mostly idealistic–they see the future through a utopian lens. Popular media largely tells a different story: that we are headed for a dystopian world.

Why is there such a gulf in the level of idealism between technologists and the media?

Mike Solana found himself asking that question on a regular basis during his work at Founder’s Fund, where he is a vice president. Founder’s Fund has a bias toward funding difficult, cutting-edge technology like gene editing, robotics, and nuclear energy. This technology that Mike was seeing made him excited about the future–which led to his creation of the podcast “Anatomy of Next.”

“Anatomy of Next” has explored biology, robotics, nuclear energy, superintelligence, and the nature of reality. Soon the podcast will be exploring how our civilization will explore and settle the solar system–specifically Mars.

I’ve listened through the entire first season of the show twice and enjoyed it so much because Mike explores questions that are on the border of philosophy and technology–questions about the nature of reality, and what makes us human–and nobody can give perfect answers to these questions. But Mike interviews top experts on the show, which provides us with a framework. Guests on “Anatomy of Next” include Nick Bostrom (the author of Superintelligence), George Church (a pioneer in gene editing), and Palmer Luckey (the founder of VR company Oculus).

Mike joins the show to talk about why he started “Anatomy of Next,” and his own perspective on the future.

", + "Episodes Title": "Technology Utopia with Michael Solana Holiday Repeat", + "Episodes Uid": "SED3570444689", + "Episodes Audio File": "edb8504f064a1f6c63bb1c00dc5cdf2f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2kn", + "Episodes ID": "01377c98-e329-11ea-91a2-973de62d3cd3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/LLVM.mp3", + "Episodes Pubdate Date": "2017-04-10", + "Episodes Summary": "

Every program gets compiled down to 1s and 0s before it can be executed against hardware. Before being translated to machine code, programs that are written in a language like Rust, Swift, or Java spend time in an intermediate representation.

In Java, this intermediate representation is Java bytecode. Many different languages–such as Scala–translate to Java bytecode, because there has been lots of optimization written to speed up Java bytecode. Java bytecode runs on the JVM–the Java Virtual Machine.

LLVM is a project that draws inspiration from the Java Virtual Machine. LLVM originally meant “low level virtual machine” but today it is just called LLVM and describes a set of compiler tools.

In today’s interview with Morgan Wilde, we explore how compilers work, how different processor hardware architectures present a problem for compilers, and why LLVM’s intermediate representation creates a layer of interoperability for any language that compiles down to that intermediate representation.

Whether you are new to compilers or have experience, this episode will appeal to you. Morgan is an excellent teacher and his enthusiasm for the subject comes through. He has a 30-minute YouTube video–A Brief Introduction to LLVM that I highly recommend.

", + "Episodes Title": "LLVM with Morgan Wilde", + "Episodes Uid": "SED3040642606", + "Episodes Audio File": "40084a194f3a8eead3828a49ea6420a7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32b", + "Episodes ID": "f66de9c8-e328-11ea-91a2-e78a50867565", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SpotifyEventDelivery.mp3", + "Episodes Pubdate Date": "2017-09-18", + "Episodes Summary": "

Spotify is a streaming music company with more than 50 million users. Whenever a user listens to a song, Spotify records that event and uses it as input to learn more about the user’s preferences. Listening to a song is one type of event–there are hundreds of others. Opening the Spotify app, skipping a song, sharing a playlist with a friend–all of these are events that provide valuable insights to Spotify.

These are not the only types of events that Spotify cares about. There are also events that occur at the infrastructure level–for example a logging server that runs out of disk space. There are events that are relevant to all the users on Spotify–for example a new album release from Taylor Swift.

An “event” is an object that needs to be registered within a system. Since there are so many events on a platform like Spotify, delivering and processing them reliably requires significant investment.

Modern Internet companies are built by connecting cloud services, databases, and internal tools together. These different systems might respond to different events in different ways. Each system subscribes to the types of events that it wants to hear. Since there are so many events, and they might be received at uneven bursts, a modern architecture has a scalable queueing system to buffer events.

To put an event on the queue, the event producer “publishes” that event to the queue. The event is then received by each “subscriber.” That’s why queueing is often known as pub/sub–publish/subscribe.

Igor Maravic is an engineer with Spotify. In this episode, he explains why pub/sub is a key element of Spotify’s infrastructure–and he describes the migration that Spotify has made from Apache Kafka to Google Cloud Pubsub.

If you like this episode, we have done many other shows about cloud infrastructure. You can check out our back catalog by downloading the Software Engineering Daily app for iOS, where you can listen to all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that.

", + "Episodes Title": "Spotify Event Delivery with Igor Maravic", + "Episodes Uid": "SED5000260886", + "Episodes Audio File": "2bf8a4d5fbefb245b1fcf390cb46ebc4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ni", + "Episodes ID": "f39871a0-e328-11ea-91a2-cb9c58bab232", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_09_SREMikeHiraga.mp3", + "Episodes Pubdate Date": "2018-04-09", + "Episodes Summary": "

Software engineers have interacted with operations teams since software was being written. In the 1990s, most operations teams worked with physical infrastructure. They made sure that servers were provisioned correctly and installed with the proper software. When software engineers shipped bad code that took down a software company, the operations teams had to help recover the system—which often meant dealing with the physical servers.

During the 90s and early 2000s, these operations engineers were often called “sysadmins,” “database admins” (if they worked on databases), or “infrastructure engineers.” Over the last decade, virtualization has led to many more logical servers across a company. Cloud computing has made infrastructure remote and programmable.

The progression of infrastructure led to a change in how operations engineers work. Since infrastructure can be interacted with through code, operations engineers are now writing a lot more code.

The “DevOps” movement can be seen through this lens. Operations teams were now writing software—and this meant that software engineers could now work on operations. Both software engineers and operators could create deployment pipelines, monitor application health, and improve the system scalability—all through written code.

Site reliability engineering (or SRE) is a newer point along the evolutionary timeline of operations. Web applications can be unstable sometimes, and SRE is focused on making a site work more reliably. This is especially important for a company that makes business applications which other companies rely on.

Mike Hiraga is the head of site reliability engineering at Atlassian. Atlassian makes several products that many businesses rely on—such as JIRA, Confluence, HipChat, and Bitbucket. Since the infrastructure is at a massive scale, Mike has a broad set of experiences from his work managing SRE at Atlassian.

One particularly interesting topic is Atlassian’s migration to the cloud. Atlassian was started in 2002, before the cloud was widely used, and they have more recently made a push to move applications into the cloud. Full disclosure: Atlassian is a sponsor of Software Engineering Daily—and they are hiring, so if you are looking for a job, check out Atlassian jobs, or send me an email directly and I’m happy to introduce you to the team.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Site Reliability Management with Mike Hiraga", + "Episodes Uid": "SED7071007174", + "Episodes Audio File": "733b26e259895c739141c29e634474b2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3a8", + "Episodes ID": "f558b0ae-e328-11ea-91a2-afe6989aef54", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DataScienceMindset.mp3", + "Episodes Pubdate Date": "2017-12-06", + "Episodes Summary": "

A company’s approach to data can make or break the business.

In the past, data was static. There was not much data, it sat in Excel, and it was interacted with on a nightly or monthly basis. Now, data is dynamic, real time and huge. To tap into available data, many industries have oriented themselves to becoming data intensive. With many new industry sectors becoming data driven, a new field called data science emerged.

As a new field, data science has attracted a lot of attention from professionals with diverse backgrounds. Describing what is data science and who is a data scientist is not easy. As technologies surrounding the field continue to evolve and new verticals are added, the discourse surrounding the field has attracted different voices putting forward their definition of the field.

In this episode, Zacharias Voulgaris joins guest host Sid Ramesh to discuss the developments in the field. He is the author of several data science books, and in today’s conversation Zacharias explains what he means by the data science mindset–including trends and misconceptions that people have on the field.  

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Data Science Mindset with Zacharias Voulgaris", + "Episodes Uid": "SED5581379433", + "Episodes Audio File": "53837dc5c16cd9fcaffd5b099798fac3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2u0", + "Episodes ID": "f82caf06-e328-11ea-91a2-d7e8bec2c3ff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/IstioServiceMesh.mp3", + "Episodes Pubdate Date": "2017-06-27", + "Episodes Summary": "

Modern software applications are often built out of loosely coupled microservices. These services can be written in different languages, by different people, but communication between services needs to be standardized. For this reason, a service proxy is useful. A service proxy is a sidecar container that sits next to a service and facilitates communications with other services.

Once every service has a sidecar proxy, that sidecar can be used as a way to communicate with a centralized control plane. The sidecar can report telemetry data to the control plane, and the control plane can be used to set policies across services, such as rules for scaling and load balancing which might vary from service to service.

Istio is an open platform to connect, manage, and secure microservices. Istio is a service mesh that uses Envoy service proxies. If all of this sounds confusing–don’t worry, we’ll explain it all in today’s interview with Varun Talwar and Louis Ryan, who work on Istio at Google.

Check out our new topic feeds, in iTunes or wherever you find your podcasts. We’ve sorted all 500 of our old episodes into categories like business, blockchain, cloud engineering, JavaScript, machine learning, and greatest hits. Whatever specific area of software you are curious about, we have a feed for you. Check the show notes for more details.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Istio Service Mesh with Varun Talwar and Louis Ryan", + "Episodes Uid": "SED6442179192", + "Episodes Audio File": "70f53f2e450168f9a2856b64c96d4007.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "46a", + "Episodes ID": "f2490882-e328-11ea-91a2-1be75f2d5575", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_11_FlutterDartRandal.mp3", + "Episodes Pubdate Date": "2018-07-11", + "Episodes Summary": "

Flutter allows developers to build cross-platform mobile apps. In our previous show about Flutter, Eric Seidel from Google described the goals of Flutter, why he founded the project, and how Flutter is built. In today’s show, Randal Schwartz talks about Flutter in more detail–including the developer experience of building Flutter apps and why he finds Flutter so exciting.

Randal is a longtime software developer who has focused mostly on web applications. He’s also the host of the popular podcast FLOSS Weekly, a show about open source software. Like many developers, Randal has stayed away from mobile development in the past. If you write a mobile application, you have historically had to build iOS and Android apps separately. That is a large up-front cost, and Flutter reduces the cost by allowing users to develop mobile apps for iOS and Android with a single codebase.

Randal has been podcasting about open source software for 12 years, so he brings historical depth to this conversation. He has also been working with Dart for several years–Dart is a language developed by Google that is used in Flutter.

", + "Episodes Title": "Flutter in Practice with Randal Schwartz", + "Episodes Uid": "SED7853865777", + "Episodes Audio File": "93e9fb8af825bd7f2b7a0f14e951cceb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "47h", + "Episodes ID": "f22c151a-e328-11ea-91a2-2b712b8764a8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_19_Botchain.mp3", + "Episodes Pubdate Date": "2018-07-19", + "Episodes Summary": "

“Bots” are becoming increasingly relevant to our everyday interactions with technology. A bot sometimes mediates the interactions of two people. Examples of bots include automated reply systems, intelligent chat bots, classification systems, and prediction machines. These systems are often powered by machine learning systems that are black boxes to the user.

Today’s guest Rob May argues that these systems should be auditable and accountable, and that using a blockchain-based identity system for bots is a viable solution to the machine learning auditability problem.

Rob is the CEO of Talla, a knowledge base provider for business teams. The Botchain project was spun out of Talla as a solution to the problem of bot identity.

In this episode, we talk about Botchain and the application of blockchain to bot identity, the current state of ICOs, and the viability of utility token ecosystems. Botchain has its own cryptotoken called “Botcoin.”

", + "Episodes Title": "Botchain with Rob May", + "Episodes Uid": "SED7680878901", + "Episodes Audio File": "74ab3003235125e8bc9d562b92cfae6f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3h3", + "Episodes ID": "f45a55d6-e328-11ea-91a2-73c85ae810a6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_13_BoxKubernetes.mp3", + "Episodes Pubdate Date": "2018-02-13", + "Episodes Summary": "

Over 12 years of engineering, Box has developed a complex architecture of services. Whenever a user uploads a file to Box, that upload might cause 5 or 6 different services to react to the event. Each of these services is managed by a set of servers, and managing all of these different servers is a challenge.

Sam Ghods is the cofounder and services architect of Box. In 2014, Sam was surveying the landscape of different resource managers, deciding which tool should be the underlying scheduler for deploying services at Box. He chose Kubernetes because it was based on Google’s internal Borg scheduling system.

For years, engineering teams at companies like Facebook and Twitter had built internal scheduling systems modeled after Borg. When Kubernetes arrived, it provided an out-of-the-box tool for managing infrastructure like Google would.

In today’s episode, Sam describes how Box began its migration to Kubernetes, and what the company has learned along the way. It’s a great case study for people who are looking at migrating their own systems to Kubernetes.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Box Kubernetes Migration with Sam Ghods", + "Episodes Uid": "SED2665377772", + "Episodes Audio File": "5af102752aecb413e2fd51e8cb9e982e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3fy", + "Episodes ID": "f496d93e-e328-11ea-91a2-2bb78f18edd9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_27_Changelog.mp3", + "Episodes Pubdate Date": "2018-01-27", + "Episodes Summary": "

At KubeCon, I had the chance to catch up with Adam Stacoviak of the Changelog, a podcast that was an inspiration for starting Software Engineering Daily. Changelog has long been one of my favorite podcasts about engineering, thanks in part to Adam’s personality.

This was a spontaneous conversation, but it was a good one.

", + "Episodes Title": "Changelog Podcasting at KubeCon with Adam Stacoviak", + "Episodes Uid": "SED1364627996", + "Episodes Audio File": "2a89ff864c66ae1be29f51944b98cbc5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "27n", + "Episodes ID": "13811cec-e329-11ea-91a2-5f38a041a79e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/docker_fork_edited.mp3", + "Episodes Pubdate Date": "2016-10-03", + "Episodes Summary": "

Docker containers changed how engineers think about building software, and the company most responsible for the widespread adoption of containers is Docker itself. Since containerization has caught on in the mainstream, companies like RedHat, Google, Huawei, and many other big players have built platform products that utilize Docker containers.

Docker containers are the unit that many engineers use to deploy their applications, but the servers that run those containers are usually on infrastructure providers like Amazon, Google, or Rackspace. This raises the question–how will Docker the company make money? Having raised $180M in equity, Docker has plenty of time to find something that works, but there are suspicions in the open source community that aggressive changes to the open source Docker project are being made by Docker the company with the long-term objective of monetization.

These changes–namely the default support for Docker Swarm–are not nefarious, but they might be less likely to occur of Docker were just an open source project, as opposed to an open source project being tended by a well-financed company. 

The New Stack broke the story about the potential Docker Fork, and Alex Williams and Joab Jackson of The New Stack join me on today’s episode. We go deep into the facts and speculations about why a fork might occur, the motivations of different key players, and the disputes within the community that have led us to this moment.

", + "Episodes Title": "Docker Fork with Alex Williams and Joab Jackson", + "Episodes Uid": "SED9547916559", + "Episodes Audio File": "6a91dd03c39a0deff40a4918360c8255.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3fn", + "Episodes ID": "f4a5dc4a-e328-11ea-91a2-5b26250c3404", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_24_SEDWebSecurityMeetup.mp3", + "Episodes Pubdate Date": "2018-01-24", + "Episodes Summary": "

Last month, Software Engineering Daily had our 4th Meetup at Cloudflare in San Francisco. For this Meetup, the format was short interviews with security specialists from Pinterest, Cloudflare, and Segment. Each of these companies has unique security challenges, but they also have overlap in their security strategies.

Nick Sullivan, Amine Kamel, and Evan Johnson are all seasoned engineers, and it was a privilege to sit down with each of them. Some topics we discussed: cryptography, secret management, incident response, and social network security.

In 2018, I am hoping to travel to several tech hubs and do Meetups. I wanted to do more of these last year, but did not plan effectively. So this year I’d like to plan them far in advance. Some locations I have in mind are New York, Los Angeles, Austin, and Seattle. If you have suggestions, or if you know of a venue that could comfortably host us, send me an email–jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Web Security at Cloudflare, Pinterest, and Segment", + "Episodes Uid": "SED8736818606", + "Episodes Audio File": "85dc10586d1cdc42d1f5db435e644332.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yi", + "Episodes ID": "f6e1a14c-e328-11ea-91a2-8f2420b2ec96", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/OpenComputeProject.mp3", + "Episodes Pubdate Date": "2017-08-14", + "Episodes Summary": "

Facebook was rapidly outgrowing its infrastructure in 2009. Classic data center design was not up to the task of the rapid influx of new users and data, photos and streaming video hitting Facebook’s servers. A small team of engineers spent the next two years designing a data center from the ground up to be cheaper, more energy efficient, and more ergonomic for the engineers who worked within.

That data center design was open sourced in 2011. Intel, Rackspace, and Goldman Sachs were the first three large organizations to join Facebook in the Open Compute Project, an effort to bring the benefits of open source collaboration to data centers.

Steve Helvie works on the Open Compute Project and he joins the show to describe how the project has evolved in the last six years–how it has affected data center design and the implications for the future.

", + "Episodes Title": "Open Compute Project with Steve Helvie", + "Episodes Uid": "SED8155309215", + "Episodes Audio File": "744ba698f35e06ad624414c8cb3bd19f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2km", + "Episodes ID": "018405cc-e329-11ea-91a2-6b41916898c0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/blockchainapps.mp3", + "Episodes Pubdate Date": "2017-04-06", + "Episodes Summary": "

Cryptocurrencies are not only a financial instrument–they are a new platform for building applications. The blockchain allows for new solutions to digital property management, micropayments, hedge fund incentives, and ad fraud.

The cryptocurrency platforms with the most traction are Bitcoin and Ethereum. Bitcoin has no central leader and is going through some growing pains with governance issues. Ethereum is led by the charismatic Vitalik Buterin.

Bitcoin and Ethereum are not competing instruments. They fulfill different technical purposes. Under current conditions of algorithm development and network infrastructure, neither Bitcoin nor Ethereum can accomplish the dreams that will one day be realized, because of the problem of distributing transaction information across nodes in the system.

If we compared cryptocurrencies to the Internet, we would not even be in the days of dial-up yet.

ConsenSys is a venture production studio that is working on several projects within the blockchain space. Mike Goldin is a software developer with ConsenSys and joins the show to talk about blockchain applications in 2017–where we are and where we are going. It was a wide ranging conversation and I hope to have Mike back in the future so we can go deeper on some of the topics we glossed over.

", + "Episodes Title": "Blockchain Applications with Mike Goldin", + "Episodes Uid": "SED7211356084", + "Episodes Audio File": "761343cc457b0c91e83fae6cc917b9da.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2m0", + "Episodes ID": "0046cb5e-e329-11ea-91a2-574c9d60c782", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/politicalbots_edited.mp3", + "Episodes Pubdate Date": "2017-04-17", + "Episodes Summary": "

Bots on the internet can be malicious, helpful, and everything in between. A bot that responds to all of your tweets might call you a socialist–that is malicious. Google crawls the web to index Google search. That is helpful. Social media marketing bots schedule 200 Twitter posts to go out throughout the day. That is either a little annoying or a little helpful depending on who you are.  

Bots are being used to amplify political viewpoints. An amplified viewpoint can serve as a gravity well for like-minded individuals, and help a sparsely supported political cause find its footing. Sometimes that amplified viewpoint is completely fictional or unfalsifiable. Real people believe that Hillary Clinton is a lizard alien because they have seen that story shared by enough Twitter bots.

So-called “fake news” is a topic that has been discussed on so many other podcasts. What is not reported is the connection between link bait and advertising fraud. When a botnet is able to make an article go viral, thousands of people organically click on the link to that article. That organic traffic is used to launder fake clicks.

These bots that are spreading “fake news” might be controlled by conspiratorial Russians. But it doesn’t have to be that complicated. Anyone who wants to make money in online advertising fraud is incentivized to make salacious media–whether it is real or fake.

Samuel Woolley is the director of research at Political Bots. He works with Jigsaw, a division of Alphabet that seeks to make the Internet safer. In today’s episode, we talk about political bots, advertising fraud, and the connection between the two.

Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

", + "Episodes Title": "Political Bots with Samuel Woolley", + "Episodes Uid": "SED8064737465", + "Episodes Audio File": "c71a5dc40e836251f3ad54d664332cf8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yh", + "Episodes ID": "f6e67294-e328-11ea-91a2-a3c580510a81", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/TypeScriptatSlack.mp3", + "Episodes Pubdate Date": "2017-08-11", + "Episodes Summary": "

Slack is an application for team communication. Users chat across mobile devices, web browsers, and a desktop application, which means Slack has three places to deploy on rather than two. And the desktop apps on Windows, Mac, and Linux are not identical, so Slack has even more places to deploy.

With so many different runtime environments, Slack needs to make technology choices that reduce the chance of errors. TypeScript allows for static typing of JavaScript. The extra compilation step checks the types of variables being passed between different places–so the errors will be discovered at compile time. In an untyped world, those errors might occur at runtime. TypeScript also unlocks the ability to put JavaScript code in an IDE, allowing for more efficient development.

Felix Rieseberg is a desktop engineer at Slack, and in today’s episode he explains the unique challenges of building Slack, and why the team moved from JavaScript to TypeScript.

TypeScript at Slack – engineering blog

", + "Episodes Title": "TypeScript at Slack with Felix Rieseberg", + "Episodes Uid": "SED6325576074", + "Episodes Audio File": "74c00b76d04b6e1e496ba66c5e0f12ab.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5oy", + "Episodes ID": "ee21e44a-e328-11ea-91a2-e7e2ac91d775", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_10_Airtable.mp3", + "Episodes Pubdate Date": "2019-05-10", + "Episodes Summary": "

Software engineering is harder than it should be. There are many people who have an app idea that they are not sure how to build. Some of these people are highly technical professionals like real estate agents, scientists, and accountants.

These professionals learn to use spreadsheets in their day-to-day work. Spreadsheets are also used widely by young people such as students. Spreadsheet users vary in terms of how familiar they are with the programmability of a spreadsheet, but there are certainly more people who have built complex spreadsheets than there are people who have built complex web apps.

Airtable is a tool for making application development easier and more accessible. The Airtable interface is similar to a spreadsheet and can be used for most spreadsheet applications. It can also serve as a rich backend database system to improve the productivity of software developers who are fully capable of building web applications.

There are high-level programmable components called Blocks and integrations with developer APIs like Twilio and Stripe.

Airtable has a permissions and collaboration system that allows interaction between engineers who might be using Airtable as a programmatic transactional database and operations members who might need to read or edit specific parts of the data on an ad hoc basis.

Howie Liu is the CEO of Airtable and he joins the show to talk about his vision for the product and the engineering problems he is working on to realize that vision. Airtable has not been trivial to build, and has required its own custom database backend and its own JavaScript rendering system.

Special thanks to Gareth Pronovost who is a full-time Airtable expert that I found on YouTube and who was generous enough to take some time to have a call with me and describe his experience using Airtable. The fact that there is a full profession around creating Airtable applications speaks to how unique this platform is.

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Airtable with Howie Liu", + "Episodes Uid": "SED2252533403", + "Episodes Audio File": "1123e1861668937b6c9a265e90950885.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3sk", + "Episodes ID": "f2ff263a-e328-11ea-91a2-af7a0f64cbc6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_19_LAMeetup.mp3", + "Episodes Pubdate Date": "2018-05-19", + "Episodes Summary": "

Data Skeptic is a podcast about machine learning, data science, and how software affects our lives. The first guest on today’s episode is Kyle Polich, the host of Data Skeptic. Kyle is one of the best explainers of machine learning concepts I have met, and for this episode, he presented some material that is perfect for this audience: machine learning for software engineers.

Second Spectrum is a company that analyzes data from professional sports, turning that data into visualizations, reports, and futuristic sports viewing experiences. We had a previous show about Second Spectrum where we went into the company in detail–it was an excellent show, so I wanted to have Kevin Squire, an engineer from Spectrum, come on the show to talk about how the company builds machine learning tools to analyze sports data. If you have not seen any of the visualizations from Second Spectrum, stop what you are doing and watch a video on it!

This year we have had three Software Engineering Daily Meetups: in New York, Boston, and Los Angeles. At each of these Meetups, listeners from the SE Daily community got to meet each other and talk about software–what they are building and what they are excited about. I was happy to be in attendance at each of these, and I am posting the talks given by our presenters. The audio quality is not perfect on these, but there are also no ads.

Thanks to Telesign for graciously providing a space and some delicious food for our Meetup. Telesign has beautiful offices in Los Angeles, and they make SMS, voice, and data solutions. If you are looking for secure and reliable communications APIs, check them out.

We’d love to have you as part of our community. We will have more Meetups eventually, and you can be notified of these by signing up for our newsletter. Come to SoftwareDaily.com and get involved with the discussion of episodes and software projects. You can also check out our open source projects–the mobile apps, and our website.

", + "Episodes Title": "Machine Learning with Data Skeptic and Second Spectrum at Telesign", + "Episodes Uid": "SED3407030820", + "Episodes Audio File": "55a3700cac4d60b9195aa7d3a8f4a6e9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ya", + "Episodes ID": "f2be33dc-e328-11ea-91a2-133ac805b74d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_07_FutureOfComputing.mp3", + "Episodes Pubdate Date": "2018-06-07", + "Episodes Summary": "

Moore’s Law states that the number of transistors in a dense integrated circuit doubles about every two years. Moore’s Law is less like a “law” and more like an observation or a prediction.

Moore’s Law is ending. We can no longer fit an increasing amount of transistors in the same amount of space with a highly predictable rate. Dennard scaling is also coming to an end. Dennard scaling is the observation that as transistors get smaller, the power density stays constant.

These changes in hardware trends have downstream effects for software engineers. Most importantly–power consumption becomes much more important.

As a software engineer, how does power consumption affect you? It means that inefficient software will either run more slowly or cost more money relative to our expectations in the past. Whereas software engineers writing code 15 years ago could comfortably project that their code would get significantly cheaper to run over time due to hardware advances, the story is more complicated today.

Why is Moore’s Law ending? And what kinds of predictable advances in technology can we still expect?

John Hennessy is the chairman of Alphabet. In 2017, he won a Turing award (along with David Patterson) for his work on the RISC (Reduced Instruction Set Compiler) architecture. From 2000 to 2016, he was the president of Stanford University.

John joins the show to explore the future of computing. While we may not have the predictable benefits of Moore’s Law and Dennard scaling, we now have machine learning. It is hard to plot the advances of machine learning on any one chart (as we explored in a recent episode with OpenAI). But we can say empirically that machine learning is working quite well in production.

If machine learning offers us such strong advances in computing, how can we change our hardware design process to make machine learning more efficient?

As machine learning training workloads eat up more resources in a data center, engineers are developing domain specific chips which are optimized for those machine learning workloads. The Tensor Processing Unit (TPU) from Google is one such example. John mentioned that chips could become even more specialized within the domain of machine learning. You could imagine a chip that is specifically designed for a LSTM machine learning model.

There are other domains where we could see specialized chips–drones, self-driving cars, wearable computers. In this episode, John describes his perspective on the future of computing, and offers some framework for how engineers can adapt to that future.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Future of Computing with John Hennessy", + "Episodes Uid": "SED5804264837", + "Episodes Audio File": "dd1a9311e217cacc7df3a32175e8f6ef.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4bp", + "Episodes ID": "f1aaa034-e328-11ea-91a2-db0a2e430498", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_20_WebAssemblyatGoogle.mp3", + "Episodes Pubdate Date": "2018-08-20", + "Episodes Summary": "

WebAssembly allows developers to run any language in a sandboxed, memory controlled module that can be called via well-defined semantics. As we have discussed in recent episodes with Lin Clark and Steve Klabnik from Mozilla, WebAssembly is changing application architectures both in and outside the browser.

WebAssembly is being adopted by all of the major browser vendors, including Google. Today’s guests are Thomas Nattestad and Ben Smith from Google. Thomas is the PM for V8, WebAssembly, Storage, and Games on the web and Ben is a software engineer on the Chrome team.

Ben and Thomas talk about the state of WebAssembly, what the different browser manufacturers are doing, and some cool uses for WebAssembly–from games to CDNs to cryptocurrency infrastructure. As in the previous episodes, there was discussion of WebAssembly’s security and memory benefits from being a bounded context.

", + "Episodes Title": "WebAssembly Engineering with Ben Smith and Thomas Nattestad", + "Episodes Uid": "SED1500028760", + "Episodes Audio File": "a144e61216fa77be4c1bac313d73eb76.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3h2", + "Episodes ID": "f45f0bd0-e328-11ea-91a2-7fde6348f1af", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_12_BoxEngineering.mp3", + "Episodes Pubdate Date": "2018-02-12", + "Episodes Summary": "

When Box started in 2006, the small engineering team had a lot to learn. Box was one of the earliest cloud storage companies, with a product that allowed companies to securely upload files to remote storage.

This was two years before Amazon Web Services introduced on-demand infrastructure, so the Box team managed their own servers, which they learned how to do as they went along. In the early days, the backup strategy was not so sophisticated. The founders did not know how to properly set up hardware in a colocated data center. The frontend interface was not the most beautiful product.

But the product was so useful that eventually it started to catch on. Box’s distributed file system became the backbone of many enterprises. Employees began to use it to interact with and share data across organizations.

The increase in usage raised the stakes for Box’s small engineering team. If Box’s service went down, it could cripple an enterprise’s productivity, which meant that Box needed to hire experienced engineers to build resilient systems with higher availability. And to accommodate the growth in usage, Box needed to predict how much hardware to purchase, and how much space in a data center to rent–a process known as capacity planning.

As Box went from 3 engineers to 300, the different areas of the company went from being managed by individuals, to teams, to entire departments with VPs and C-level executives.

Jeff Quiesser is an SVP at Box, and one of the earliest employees. He joins the show today to describe how Box changed as the company scaled. We covered engineering, management, operations, and culture.

In previous shows, we have explored the stories of companies like Slack, Digital Ocean, Giphy, Uber, Tinder, and Spotify. It’s always fun to hear how a company works–from engineering the first product to enterprises with millions of users. To find all of our episodes about how companies are built, download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Scaling Box with Jeff Quiesser", + "Episodes Uid": "SED3472125108", + "Episodes Audio File": "3da1540a12a7d314ae4fe4f27bb4fbe5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "27w", + "Episodes ID": "134db6f4-e329-11ea-91a2-bff131266c09", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/scalajs_edited.mp3", + "Episodes Pubdate Date": "2016-10-06", + "Episodes Summary": "

Scala is a functional programming language built on the JVM. For more than a decade, this didn’t mean anything to front end web developers. More recently, ScalaJS has brought Scala to the front end. ScalaJS is a project that compiles any Scala program down to JavaScript–so that all of your Scala programs can run on the browser.

Haoyi Li has worked on ScalaJS extensively and has written an online book about ScalaJS. If you are a front end developer looking for a safer way to write your web apps, you will like this episode–or if you are a fan of functional programming.

", + "Episodes Title": "ScalaJS with Haoyi Li", + "Episodes Uid": "SED8380736854", + "Episodes Audio File": "b3837b86545bb2b028401f60a101d140.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5qj", + "Episodes ID": "ee0d5020-e328-11ea-91a2-1720aa042985", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_16_FBDanAbramov.mp3", + "Episodes Pubdate Date": "2019-05-16", + "Episodes Summary": "

React is a set of open source tools for building user interfaces. React was open sourced by Facebook, and includes libraries for creating interfaces on the web (ReactJS) and on mobile devices (React Native).

React was released during a time when there was not a dominant frontend JavaScript library. Backbone, Angular, and other JavaScript frameworks were all popular, but there was not any consolidation across the frontend web development community. Before React came out, frontend developers were fractured into different communities for the different JavaScript frameworks.

After Facebook open sourced React, web developers began to gravitate towards the framework for its one-way data flow and its unconventional style of putting JavaScript and HTML together in a format called JSX. As React has grown in popularity, the React ecosystem has developed network effects. In many cases, the easiest way to build a web application frontend is to compose together open source React components.

After seeing the initial traction, Facebook invested heavily into React, creating entire teams within the company whose goal was to improve React. Dan Abramov works on the React team at Facebook and joins the show to talk about how the React project is managed and his vision for the project.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Facebook React with Dan Abramov", + "Episodes Uid": "SED7738462466", + "Episodes Audio File": "f2d269cd678e3efda935788bf1334373.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4u9", + "Episodes ID": "f0bc98b2-e328-11ea-91a2-a39a5dd7037a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_31_Diffbot.mp3", + "Episodes Pubdate Date": "2018-10-31", + "Episodes Summary": "

Google Search allows humans to find and access information across the web. A human enters an unstructured query into the search box, the search engine provides several links as a result, and the human clicks on one of those links. That link brings up a web page, which is a set of unstructured data. Humans can read and understand news articles, videos, and Wikipedia pages.

Google Search solves the problem of organizing and distributing all of the unstructured data across the web, for humans to consume. Diffbot is a company with a goal of solving a related, but distinctly different problem: how to derive structure from the unstructured web, understand relationships within that structure, and allow machines to utilize those relationships through APIs.

Mike Tung is the founder of Diffbot. He joins the show to talk about the last decade that he has spent building artificial intelligence applications, from his research at Stanford to a mature, widely used product in Diffbot. I have built a few applications with Diffbot, and I encourage anyone who is a tinkerer or prototype builder to play around with it. It’s an API for accessing web pages as structured data.

Diffbot crawls the entire web, parsing websites, using NLP and NLU to comprehend those pages, and using probabilistic estimations to draw relationships between entities. It’s an ambitious product, and Mike has been working on it for a long time. I enjoyed our conversation.

We recently launched a new podcast: Fintech Daily! Fintech Daily is about payments, cryptocurrencies, trading, and the intersection between finance and technology. You can find it on fintechdaily.co or Apple and Google podcasts. We are looking for other hosts who want to participate. If you are interested in becoming a host, send us an email: host@fintechdaily.co

", + "Episodes Title": "Diffbot: Knowledge Graph API with Mike Tung", + "Episodes Uid": "SED7868786475", + "Episodes Audio File": "ac446821dd0e9a75df6d92c87697ace5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "63c", + "Episodes ID": "ecafb1a0-e328-11ea-91a2-4fdf7f89ccc1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_21_TimeSeriesDatabases.mp3", + "Episodes Pubdate Date": "2019-08-21", + "Episodes Summary": "

A time series database is optimized for the storage of high volumes of sequential data across time.

Time series databases are often organized as columnar data stores that can write large volumes of data quickly. These systems can sometimes tolerate data loss, because the data they are gathering is used for monitoring and other applications that require aggregated data sets rather than highly important individual transactions.

The demand for time series databases has grown over the last decade with the rise of mobile devices and the decreasing cost of cloud storage. There has been an increase in the number of systems that require monitoring, and some of those systems produce an incredibly large amount of data, requiring compression, downsampling, and garbage collection.

Rob Skillington is an engineer at Uber, where he helped create M3DB, a time series database. In a previous show, Rob described the basics of M3DB and how it helps Uber with storing data from Prometheus, a monitoring system. In today’s show we discuss the field of time series databases, and Rob’s approach to building M3.

", + "Episodes Title": "Time Series Databases with Rob Skillington", + "Episodes Uid": "SED2898692061", + "Episodes Audio File": "c00929f7ca8344fc8a6791a95c5ac174.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3b0", + "Episodes ID": "f53ebd5c-e328-11ea-91a2-1b2974a6afaa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/KeyValues.mp3", + "Episodes Pubdate Date": "2017-12-13", + "Episodes Summary": "

The values system of a company guides the actions of the engineers who work at that company.

Some companies value open communication and a flat organization where anybody can talk to anyone else. Other companies encourage hierarchy and secrecy, so that employees are focused on their specific section of the company.

Some companies take themselves seriously, and have a work environment that is as stoic as the military. Other companies pride themselves on having good beer and a friendly, laid back atmosphere.

When company values are properly defined, the values can be used as reference points when making decisions. At Amazon, one of the core company values is “bias for action.” As an engineer, you are often in a situation where you can wait for more information, or you can start a project with an incomplete picture for how you will finish it. The “bias for action” lets you know that you should usually start the project despite having an incomplete picture.

Another use of a company values system is for hiring.

When a company publishes their values, prospective employees can use those stated values as a way to know if they would be a good cultural fit. For example “move fast and break things” was a value that allowed Facebook to ship new products faster than any other company before it. But the speed of movement is not for everyone. Some engineers like to have their code unit tested, and free of all bugs before shipping to production.

Every company has values that define their company. And every engineer has values that define how they want to work.

Lynne Tye started her company Key Values as a platform to index companies by their values systems. This allows engineers to find companies that are a good cultural fit for their values system. Lynne joins the show today to explain how engineers and companies define their values systems, and how that affects the outcomes of engineering organizations.

Lynne also talks about her time at HomeJoy, one of the first companies in the “gig economy”. HomeJoy was an on-demand house cleaning service that grew extremely fast, but ultimately went under due to lawsuits. The challenges of HomeJoy were a predictor of the challenges later faced by Uber and Airbnb, and it was fascinating to hear Lynne reflect on her time spent managing operations at HomeJoy–which was about as operationally intensive a company as you can imagine!

Thanks to Courtland Allen for the intro to Lynne, and if you haven’t checked out the Indie Hackers podcast, which is hosted by Courtland, you should subscribe to it. Indie Hackers breaks down the engineering and business models behind small software companies–it’s one of my favorite shows.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Engineering Values with Lynne Tye", + "Episodes Uid": "SED2524027101", + "Episodes Audio File": "6da88cd9801aec6167e0d73620c19956.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2lp", + "Episodes ID": "009ca06a-e329-11ea-91a2-e7dc7caa3850", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/panopticlick_edited.mp3", + "Episodes Pubdate Date": "2017-04-13", + "Episodes Summary": "

The Internet is decreasing in privacy and increasing in utility. Under some conditions, this tradeoff makes sense. We publicize our profile photo so that people know what we look like. Under other conditions, this tradeoff does not make sense. We do not want a television that costs less to purchase because it is silently recording all of the conversations that take place in the room and selling them to the highest bidder.

The example of the TV that records everything you say (which is a real thing) illustrates a tradeoff of the Internet. The advertising industry pushes us towards lower marginal costs for products and services in exchange for less privacy.

Someday we will live in a world where it will be easy for consumers to control the dial on the tradeoff between privacy and the price of their services. Until then, we have almost zero control over what information the advertising surveillance industrial complex knows about us.

Bill Budington is a security engineer with the Electronic Frontier Foundation. In today’s episode, Bill describes some of the current techniques used by the advertising industry to track your activity through the web. Bill works on encryption tools as well as Panopticlick, a project that allows users to see what trackers they are vulnerable to.

Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

", + "Episodes Title": "Web Tracking with Bill Budington", + "Episodes Uid": "SED9894257464", + "Episodes Audio File": "4504413ad3ddec2ce454ca5b203000d9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3nx", + "Episodes ID": "f38504bc-e328-11ea-91a2-130ec7f44561", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_13_Unchained.mp3", + "Episodes Pubdate Date": "2018-04-13", + "Episodes Summary": "

Laura Shin is the host of Unchained, a podcast about cryptocurrencies and decentralized technology. For every episode, Laura does significant research and preparation, so the content turns out polished and high quality. Her enthusiasm for the subject of cryptocurrencies comes through in her reporting.

Podcasting about cryptocurrencies requires walking a fine line. Cryptocurrencies have a mixture of drama and exciting technology–which are both great for a journalist. But you can’t get too deep in the drama, because the podcast will feel like a tabloid. And you can’t get too deep in the technical weeds, because the listener will fall asleep.

Laura joins the show to discuss how she got into reporting on cryptocurrencies, why she got so obsessed with the subject, and her experience as a solo entrepreneurial journalist.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Unchained with Laura Shin", + "Episodes Uid": "SED7151055358", + "Episodes Audio File": "f5bfd2b689354e1a7758a7840225b6f9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2rf", + "Episodes ID": "fa7925b4-e328-11ea-91a2-6b98554d0de7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/dataskeptic_edited.mp3", + "Episodes Pubdate Date": "2017-05-31", + "Episodes Summary": "

With a fast-growing field like data science, it is important to keep some amount of skepticism. Tools can be overhyped, buzzwords can be overemphasized, and people can forget the fundamentals.

If you have bad data, you will get bad results in your experimentation. If you don’t know what statistical approach you want to take to your data, it doesn’t matter how well you know Spark or TensorFlow. And if you aren’t passionate about the work you are doing, you are unlikely to finish the projects you start (whether we are talking data science or otherwise).

Kyle Polich hosts the Data Skeptic podcast, a show at the intersection of data science and skepticism. As a podcaster, Kyle takes himself seriously and is prepared for his shows–which I admire. Having met him recently at the Microsoft Build conference, he’s a great guy and I look forward to doing more podcasts with him in the future.

In this episode, Kyle is interviewed by Sid Ramesh, a data engineering  correspondent for Software Engineering Daily.

https://dataskeptic.com

http://openhouseproject.co

", + "Episodes Title": "Data Skepticism with Kyle Polich", + "Episodes Uid": "SED3418615787", + "Episodes Audio File": "5598b566df3fd20672ad9868ff4b7569.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4w9", + "Episodes ID": "f09becf2-e328-11ea-91a2-9fad3177e13f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_09_TLA.mp3", + "Episodes Pubdate Date": "2018-11-09", + "Episodes Summary": "

TLA+ is a formal specification language. TLA+ is used to design, model, and verify concurrent systems. TLA+ allows a user to describe a system formally with simple, precise mathematics.

TLA+ was designed by Leslie Lamport, a computer scientist and Turing Award winner. Leslie joins the show to talk about the purpose of TLA+. Since its creation in 1999, TLA+ has been used to discover bugs in systems such as Amazon S3, DynamoDB, Xbox, and Cosmos DB.

“TLA” stands for “temporal logic of actions”, a logical system that can be used to describe the behaviours of concurrent systems.

This podcast is meant as a brief introduction of TLA+. To go deeper, check out the TLA+ website and the TLA+ video course (note: these videos are highly entertaining because of Leslie’s dry, unpredictable sense of humor).

", + "Episodes Title": "TLA+ with Leslie Lamport", + "Episodes Uid": "SED3001208688", + "Episodes Audio File": "b3c6ebbb1a65276a73cc49d7a11a7ae8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5pp", + "Episodes ID": "ee1781da-e328-11ea-91a2-cb7ce91314a1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_14_FBNickSchrock.mp3", + "Episodes Pubdate Date": "2019-05-14", + "Episodes Summary": "

When Facebook was scaling in its early years, the company developed engineering practices that were unlike any other organization before it.

Early Facebook engineering developed unusual practices because the problem set was unusual. Facebook was a highly detailed, highly interactive, multi-user web application. Facebook was pushing the limits of PHP and JavaScript in a time when there were not simple frameworks to help with user interface development and data fetching.

In addition to unique engineering problems, the Facebook product itself was also unique. When a product has as much traction as Facebook did in the early days, how are you supposed to manage the direction of that product?

Should you double down on the core competency of the product, and make it as good as possible at simply connecting friends to each other? Or should you rapidly expand into adjacent systems like messaging, groups, and photos? How should you allocate developer resources when you have problems to be solved at every layer of the stack, from backend infrastructure to frontend performance?

At a typical company, you would put all these engineering problems and product opportunities into some kind of project management software and assign developers to work on them, and gradually make steady, measured progress. The downside of that approach is that it slows down the pace of product creation and experimentation, and turns software development into a top-down, bureaucratic process.

At Facebook, developers self-assembled into teams that did what needed to be done. The engineers who were the most productive and charismatic could quickly build a reputation for themselves and become technical leaders. These “influencer engineers” within Facebook had a proven track record, and would become magnets for other engineers who wanted to contribute to the projects with the most momentum.

Facebook is a case study in the ability for developers to self-organize into groups who are working on projects that are meaningful to the company and personally satisfying to the individual engineers. Many engineers in the software industry work under a less capable manager who has complete control over their creativity. This leads to employee churn, dissatisfaction, and burnout.

Facebook’s ability to move fast is predicated on its ability to match engineers with problems that are interesting to those particular individuals. Whether you want to work on newsfeed or developer productivity tools or machine learning research, there is a path within Facebook to finding a problem that is both important and fun.

Facebook’s unique set of engineering challenges required the company to develop a unique set of internal tools. Because Facebook had data and throughput requirements which were unprecedented, the available tools and best practices at the time did not satisfy Facebook’s requirements. Over the years, Facebook has developed its own databases, caching strategies, and JavaScript frameworks.

Nick Schrock worked at Facebook for eight years. He is best known as a co-creator of GraphQL, a tool for efficiently fetching data through a federated request language. GraphQL was the result of years of evolution of internal tooling within Facebook.

Nick has discussed the creation of GraphQL in other podcasts, and we will have a more dedicated episode around a retrospective of GraphQL in the near future. Today’s episode is about the process by which developers at Facebook self-organized, and Nick’s ideas around how to identify a need for an internal tool.

Since leaving Facebook, Nick has parlayed his experience in developer tools into Dagster, a programming model for data applications.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Facebook Developers with Nick Schrock", + "Episodes Uid": "SED8240113896", + "Episodes Audio File": "5830a74b88fa2d556cd3d23aa3dfb085.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3k5", + "Episodes ID": "f4133ffc-e328-11ea-91a2-bbaedfde454f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_05_SmartAgriculture.mp3", + "Episodes Pubdate Date": "2018-03-05", + "Episodes Summary": "

Farms have lots of data. A corn farmer needs to monitor the chemical composition of soil. A soybean farmer needs to track crop yield. A chicken farmer needs to count the number of eggs produced.

If this data is captured, it can be acted upon—for example, a dry farm can automatically turn up its irrigation system. Or the data can simply be studied.

If you work in a pure software business, you might take for granted how easy it is to track your metrics. On the farm, you need to use sensors and drones to gather your data.

Mike Prorock is the CTO of Mesur.io, a company that makes sensors and software infrastructure for agriculture. He joins the show to describe the use cases for agriculture technology, and the architecture behind it.

Today’s episode is a great complement to our recent episodes on streaming data. Mesur.io offers a case study in how streaming systems can be put into practice. Mike will also be speaking at the upcoming Strata Data Conference in San Jose.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Smart Agriculture with Mike Prorock", + "Episodes Uid": "SED4686768286", + "Episodes Audio File": "f251a55e95c1f0b92248a7b9b6723f0f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 469, + "Episodes ID": "f24f5eb2-e328-11ea-91a2-1f921acdb8f9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_10_Nubank.mp3", + "Episodes Pubdate Date": "2018-07-10", + "Episodes Summary": "

Nubank was started in 2013 with a credit card that was controlled through a mobile app. At the time, it was the first service in Brazil that allowed customers to do banking without going to a physical bank branch. Since then, Nubank has expanded into additional financial services and currently has 850 employees working in Brazil.

Edward Wible is a co-founder and CTO of Nubank and in this episode he discusses his work growing Nubank from a small team of less than 10 people into a company with almost 1000 people.

We have covered two other banks in the past few weeks: Monzo and N26. In terms of software engineering and product management, Nubank is similar to Monzo and N26. One characteristic that stood out was Nubank’s use of Clojure, a functional programming language built on the JVM.

A question that came up during this show: what is the line between “fintech company” and “bank”? We hope explore this more in future shows about the intersection of money and software.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Build a Bank: Nubank with Edward Wible", + "Episodes Uid": "SED2798759335", + "Episodes Audio File": "7e8d9879a4b4a18e9f057c0c6329584d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2if", + "Episodes ID": "0586418a-e329-11ea-91a2-8ba46fc6bea0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/manufacturing_edited.mp3", + "Episodes Pubdate Date": "2017-03-03", + "Episodes Summary": "

Manufacturing electronics is not a simple task and because of its complexity it is also quite expensive. Companies like Apple are able to pull their costs down through economies of scale. Since Apple is always placing huge bulk orders on chips, sensors, and other components, the company can get lower prices for those components than an individual hardware hacker that wants to build a prototype.

Herein lies the opportunity for Tempo Automation, a company that allows rapid prototyping of electronics. By aggregating demand for electronics prototyping, Tempo Automation can offer competitive pricing and speed to anyone who needs a hardware prototype.

I visited Tempo Automation and was given a tour of the production floor by CEO Jeff McAlvay. He showed me the huge machines that are used to build hardware prototypes and explained how they work in serial to produce prototypes. He also mentioned that anyone can schedule a tour of Tempo Automation’s factory by going to their website, and I highly recommend it. After the tour, Jeff and I sat down for an interview about what Tempo Automation is building and their plans for the future.

", + "Episodes Title": "Prototype Manufacturing with Jeff McAlvay", + "Episodes Uid": "SED5574911618", + "Episodes Audio File": "885c876db0eab8bf532e69ba7265d7c1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3zt", + "Episodes ID": "f28e0090-e328-11ea-91a2-0ba022318247", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_20_Babel.mp3", + "Episodes Pubdate Date": "2018-06-21", + "Episodes Summary": "

Different browsers consume JavaScript in different ways.

When a new version of JavaScript comes out, developers are eager to use the new functionality of that language version. But if you are writing frontend JavaScript code, that code needs to be interpretable by every browser that might consume it–whether the consumer is on an iPhone running Safari or a Windows machine running Internet Explorer 11.

Babel is a transpiler for JavaScript. Babel allows new versions of JavaScript to be consumed by older browsers by translating new language features of JavaScript into code that is readable by an older JavaScript interpreter. Babel does this by parsing JavaScript code, creating an abstract syntax tree, and manipulating the AST to make that code comply with the old browser.

Henry Zhu is a core maintainer of Babel and a full-time open source developer. In today’s episode, Henry explains how Babel works and its various applications. He also talks about life as a full-time open source developer, where he earns a living through Patreon and OpenCollective.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Babel with Henry Zhu", + "Episodes Uid": "SED7989106246", + "Episodes Audio File": "6b4ef9933105d75fc14bbfa68bc27fa4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 624, + "Episodes ID": "ecbe0462-e328-11ea-91a2-6721d2bdd033", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_16_BitcoinAndreasAntonopoulos.mp3", + "Episodes Pubdate Date": "2019-08-16", + "Episodes Summary": "

Andreas Antonopoulos is the author of several books about cryptocurrency engineering, including Mastering Bitcoin and Mastering Ethereum. In these books, Andreas lays out the systems of economics and computer science that underpin the two most mature decentralized monetary systems.

When Andreas originally discovered the Bitcoin whitepaper, he had witnessed the repeated mismanagement of government-backed fiat currencies. Andreas has a Greek background, and the financial collapse of 2008 had led to an economic crisis in Greece. His firsthand observation of the weaknesses of centrally planned government currencies, together with a degree in computer science and distributed systems have made him a dedicated evangelist for Bitcoin.

Andreas joins the show to discuss the Bitcoin ecosystem, and the relationship between decentralized cryptoeconomic systems and centralized corporations. Facebook has recently announced a cryptocurrency project called Libra, and Andreas suggests that Libra changes everything–not necessarily because Libra will make it to production, or because Libra itself will upend the world of finance–but because it allows us to further call into question the very nature of what makes a modern currency valuable and valid. 

After all, if a large government has the right to back a currency, why shouldn’t a large corporation have that same privilege?

Andreas is also a co-host of one of my favorite Bitcoin podcasts, Let’s Talk Bitcoin.

", + "Episodes Title": "Bitcoin Ecosystem with Andreas Antonopoulos", + "Episodes Uid": "SED6598476129", + "Episodes Audio File": "77761c44a39418a3b586cecb74b21f9d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4xr", + "Episodes ID": "f089d47c-e328-11ea-91a2-978ed388b1b7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_15_LiquidSoftware.mp3", + "Episodes Pubdate Date": "2018-11-15", + "Episodes Summary": "

The software release process is a barrier between written code and a live production environment that affects users. A software release process can involve a variety of different practices. Code might be tested for bugs using automation and manual testing. Static analysis tools can look at the code for potential memory leaks. A software release might go out to a small percentage of the total user base before it gets deployed to the entire audience.

At some organizations, a software release can be slow and painful. The release might be bottlenecked by a manual approval step, which slows down developers from quickly deploying their own changes. If a consistent version history of software is not maintained, a release can be hard to roll back in the event of an error. In the case of a large, monolithic architecture, a release can be scary, because it can be hard to understand how the monolithic codebase functions.

This set of challenges within the release process lowers the quality of software, and can make it frustrating to build software. The release process is just one area of software development that many organizations have a desire to smooth out.

Over the past ten years, a set of technologies and philosophies have provided improvements to the software development process. DevOps, continuous delivery, microservices, cloud providers, and serverless tools all make it easier for a company to focus on its core competency and release software faster.

Baruch Sadogursky is an author of Liquid Software, a book about continuous updates and DevOps. Liquid Software describes an idealized vision of what today’s architecture could aspire to. The focus of the book is continuous updates, which allow for rapidly improving, evolving software quality. Baruch joins the show to discuss how software has changed in the last twenty years, and how the future of software development could look. Full disclosure: Baruch works at JFrog, which is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Liquid Software with Baruch Sadogursky", + "Episodes Uid": "SED2071591517", + "Episodes Audio File": "22a56d85e1eb94a6466dc95aa484aa5b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3bq", + "Episodes ID": "f526be82-e328-11ea-91a2-8b0055c593b4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ManagingEngineers.mp3", + "Episodes Pubdate Date": "2017-12-20", + "Episodes Summary": "

“Management is about human beings. Its task is to make people capable of joint performance. To make their strengths effective and their weaknesses irrelevant.” That quote is from Peter Drucker.

It is one of the many useful quotes collected in Ron Lichty’s book “Managing the Unmanageable”—and it illustrates why we work in teams. When we collaborate with each other, we make each other’s strengths effective, and our weaknesses become irrelevant.

To collaborate effectively, we need leaders. We need management.

Ron Lichty spent 6 years managing engineers at Apple, and many more years in management and director roles elsewhere. In his book, Ron lays out the lessons he learned in 30 years of engineering management. Ron also describes concrete strategies for how to manage engineers productively.

An engineer who becomes a manager needs to learn new skills. And the hardest skills to master have nothing to do with technology.

Prioritizing the right projects, allocating engineering resources, making architectural decisions—all of those skills are important. But the art of relationships—of diplomacy and language—is harder to learn than any technical skill.

How do you motivate an engineer to do something that is boring? How do you have a difficult conversation with an engineer who needs to improve?  When a conflict between engineers comes up, do you confront the conflict head-on, or do you wait for those engineers to resolve it among themselves?

These questions do not have easy answers. The best way to learn how to react to these situations is to live through them. The second best way to learn is to read and listen to people who have seen so much of the management dynamic that they can distill it into anecdotes and aphorisms.

In today’s show, Ron shares several stories that changed how I think about management.

Ron and I did not have time to discuss everything I wanted to, and I recommend checking out his podcast episode on Software Engineering Radio for more detail. And also check out his book—Managing the Unmanageable.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Managing Engineers with Ron Lichty", + "Episodes Uid": "SED7038039317", + "Episodes Audio File": "8fb2af385bff795f0f731ccf0fbd2b22.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "54f", + "Episodes ID": "f019e810-e328-11ea-91a2-771f3e86da53", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_19_Linkerd2.mp3", + "Episodes Pubdate Date": "2018-12-19", + "Episodes Summary": "

Software products are distributed across more and more servers as they grow. With the proliferation of cloud providers like AWS, these large infrastructure deployments have become much easier to create. With the maturity of Kubernetes, these distributed applications are more reliable.

Developers and operators can use a service mesh to manage the interactions between services across this distributed application.

A service mesh is a layer across a distributed microservices application that consists of service proxy sidecars running alongside each service in a cluster, along with a central control plane for communicating with those sidecar proxies.

A service mesh has many uses. Every request and response within the application gets routed through the service proxy, which can improve observability, traffic control to different instances, and circuit breaking in case of an instance failure. The central control plane can be used manage network policy throughout the whole system.

We have done shows about each of the different components of a service mesh system, including different types of service proxies, as well as the service meshes built on top of these proxies.

Linkerd, which is made by the startup Buoyant, was the first service mesh product to come to market, and it has the most production use, with customers like Expedia and Monzo bank. Istio is a more recent service mesh which uses the Envoy service proxy. Istio came out of Google and is also supported by IBM—setting up a classic competition between a startup and the large incumbents.

William Morgan is the CEO of Buoyant, and he joins the show to talk about the use cases and adoption of service mesh. He also talks about the business landscape of the service mesh category, and how to compete with giant cloud providers.

", + "Episodes Title": "Linkerd Service Mesh with William Morgan", + "Episodes Uid": "SED4473034832", + "Episodes Audio File": "eea12ba7771198e453886e61e2bae33e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5h8", + "Episodes ID": "eeda0b88-e328-11ea-91a2-3b9bf920b5ef", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_21_FaunaDB.mp3", + "Episodes Pubdate Date": "2019-03-21", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Twitter’s early engineers faced scalability problems that caused infrastructure failures on a regular basis. The infamous “fail whale” could happen as a result of problems in the application servers, the network, or the database layer.

When Twitter was scaling in its early days, the cloud providers were still immature. Engineers did not have access to the autoscaling cloud infrastructure that is available today. The early Twitter architecture was a combination of open source tools and internally created infrastructure custom built for Twitter’s workloads.

Evan Weaver was an early engineer at Twitter, and he saw the deficiencies of the data tools that the company had access to. Twitter engineers wanted access to a truly reusable data platform that would fit Twitter’s requirements: high availability, globally replicated, and transactionally consistent.

By 2012, Evan had left Twitter and started consulting for other technology companies. He found that databases across the industry were lacking the same properties that Twitter wanted, and the ideas for FaunaDB began to percolate. Around this time, there were two relevant papers about distributed databases that had come out: the Spanner paper from Google and the Calvin paper, a distributed systems paper from Yale.

With inspiration from the literature, his time at Twitter, and his knowledge from consulting, Evan started FaunaDB. Seven years later, FaunaDB is a fully fledged open source project as well as a database company with a cloud service offering. Fauna is an OLTP database used by companies like Nvidia, Nextdoor, and Capital One.

Evan joins the show to talk about his time spent scaling Twitter and the architecture of FaunaDB.

", + "Episodes Title": "FaunaDB with Evan Weaver", + "Episodes Uid": "SED9736432469", + "Episodes Audio File": "de2c0225c32b40e680c094247aea49f7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5du", + "Episodes ID": "ef3cd7d6-e328-11ea-91a2-1fcc942aa757", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_26_AWSIOT.mp3", + "Episodes Pubdate Date": "2019-02-26", + "Episodes Summary": "

Many devices in our world are not “smart.” Air conditioners, electric guitars, power outlets, and factory conveyor belts, just to name a few. There are exciting software applications that we could build around these devices, but we need to be able to interface with them programmatically.

We need to be able to know the state of these devices. We need to be able to save that state, and then we can use that state data to perform actions that change the state of those devices. To make these devices smart, we can use a microcontroller, a small device with a constrained amount of CPU, memory, and I/O.

Device data can be sent to the cloud or processed locally, and that data can be used perform predictive maintenance, or create machine learning models, or create simple dashboards so human operators can understand the state of their hardware.

Dirk Didascalou is the VP of Internet of Things with Amazon Web Services. Dirk joins today’s show to discuss the strategy and philosophy of the AWS Internet of Things set of tools. We talk about a wide-ranging set of topics–including IoT security, edge deployments, and machine learning.

", + "Episodes Title": "AWS Internet of Things with Dirk Didascalou", + "Episodes Uid": "SED2102926468", + "Episodes Audio File": "aaeeb661776841304eda73d0b47487ac.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 471, + "Episodes ID": "f2311524-e328-11ea-91a2-47d336c38423", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_18_N26.mp3", + "Episodes Pubdate Date": "2018-07-18", + "Episodes Summary": "

Banking has been a part of the economy for 600 years. Banking has always been evolving.

The most recent evolution: the financial industry has been going digital. Newer “fintech” companies have created innovative ways of doing everything related to money–from friendly payments to budgeting; from business transactions to insurance. However, the traditional banks themselves have been relatively slow at adjusting to these digital changes, creating the opportunity for native digital banks–often referred to as “challenger banks.”

N26 is a digital first bank established in Berlin and is active in 17 European countries with a million users. Pat Kua is the CTO at N26.

Digital banks are hosted on the cloud, without a physical branch the user must go to to perform an operation. The user accesses their account through a mobile application, and can complete everything online from opening an account to performing transactions. This system has numerous advantages, like simplicity for the user, and higher scalability in terms of users from the bank’s perspective.

In this episode, we discuss the advantages of digital banks, the fintech industry and N26 as a itself. We also explore product development and how Pat manages his time as CTO–which is a useful discussion for anyone who is learning to be a technical leader or manager.

", + "Episodes Title": "Build a Bank: N26 with Pat Kua", + "Episodes Uid": "SED1858536367", + "Episodes Audio File": "15e83268e0e609e5ac10b0e9fdc7a52d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2se", + "Episodes ID": "f9d15d2a-e328-11ea-91a2-3f536cf675ca", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/HTBox.mp3", + "Episodes Pubdate Date": "2017-06-09", + "Episodes Summary": "

Microsoft’s past is full of stories. It’s early period of corporate domination in the 1990s was followed by a period of government antitrust scrutiny, and a period of unsure product direction. Today, Microsoft’s focus on cloud has allowed the company to regain its footing with a clear trajectory for growth.

Since 2002, Richard Campbell has chronicled the Microsoft developer community as co-host of .NET Rocks!, a podcast that was originally about the C# .NET framework. Richard also founded Humanitarian Toolbox, an open source set of tools for assisting disaster relief organizations.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Microsoft History with Richard Campbell", + "Episodes Uid": "SED5011932498", + "Episodes Audio File": "7051f500fe9e616b969425cfb36dfefb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3sn", + "Episodes ID": "f2f0ea0c-e328-11ea-91a2-d7043dcb06b7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_23_LawandSoftware.mp3", + "Episodes Pubdate Date": "2018-05-23", + "Episodes Summary": "

The world of software moves faster than the laws that regulate it. When software companies do get regulated, that regulation is often enforced unevenly among different companies.

Software continually presents the legal system with new requirements. Consumer data privacy needs to enforced on a granular level. Software developers need a system of protecting their intellectual property. When a company becomes dominant, our legal system needs to scrutinize that company for potential antitrust violations.

Micah Kesselman is a lawyer specializing in software IP prosecution. Prior to becoming a lawyer, he studied computer science. He joins the show to discuss a range of issues at the intersection of software and the law–including GDPR, software patents, and self-driving cars.

These are topics we will cover in more detail in the future, but it was great to have Micah bring the perspective of a lawyer to the show.

Massachusetts Autonomous Vehicles Working Group

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Software Law: GDPR, Patents, and Antitrust with Micah Kesselman", + "Episodes Uid": "SED4592300020", + "Episodes Audio File": "b321a415c1f9af6a2feb8bdb4cf86b3d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2tt", + "Episodes ID": "f87bb3c6-e328-11ea-91a2-0345d8527124", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SearchEngineLand.mp3", + "Episodes Pubdate Date": "2017-06-23", + "Episodes Summary": "

Search engines run our lives. The path we take to information is dictated by Google, Facebook, Amazon, and other forms of search. Search engines feel objective and truthful, but are built through ongoing experimentation and subjective decision making.

That’s what has kept Danny Sullivan writing about search engines for twenty years.

The content Google prioritizes, the ads that we see, the way that a product review changes how highly a search result appears on a search; these are the topics that Danny studies. He is the founder of Search Engine Land, an invaluable resource for news and updates about search engines and marketing. I’ve been reading Search Engine Land since college, so it was a treat to sit down for a conversation with him.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Search Engine Land with Danny Sullivan", + "Episodes Uid": "SED7079176110", + "Episodes Audio File": "350c8cbdece8f8ccf9a9d4beea292500.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3gc", + "Episodes ID": "f488c6c8-e328-11ea-91a2-abfb8459c00c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_31_SueLoh.mp3", + "Episodes Pubdate Date": "2018-01-31", + "Episodes Summary": "

Sue Loh is a software engineer and author of a book with the goal of breaking developer stereotypes. Stereotyping among developers leads to bad outcomes. When incorrect assumptions are made about certain populations, those populations feel marginalized and engineering resources get misallocated.

From the perspective of Sue, the main problem is about how children are socialized. Young girls in particular are discouraged from programming, leading to a steady decline in the percentage of women in the computing workforce. With her book, Sue is hoping to create a piece of literature that will expose young female and minority students to the world of technology, and help them realize how cool engineering can be. Sue created a Kickstarter around her book, and has raised more than $40,000.

Sue also describes her experiences as an engineer who has risen through the ranks at Microsoft, and how her perspective on engineering has evolved as she has become a principal engineer.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Developer Stereotypes with Sue Loh", + "Episodes Uid": "SED1983740380", + "Episodes Audio File": "655892b280306b9d146bf1651c8389b8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5nt", + "Episodes ID": "ee2beab2-e328-11ea-91a2-e35120ab7dad", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_06_WebAssemblyTyler.mp3", + "Episodes Pubdate Date": "2019-05-08", + "Episodes Summary": "

WebAssembly is a binary instruction format for applications to run in a memory-constrained, stack-based virtual machine. The WebAssembly ecosystem consists of tools and projects that allow programs in a variety of languages to compile into WebAssembly and run in a safe, fast, sandboxed runtime environment.

WebAssembly is a transformative technology for the Internet. Most users will experience it as a set of gradual, incremental improvements to their online experiences. Pages will load faster and become more dynamic. Applications will become more secure. Infrastructure will become cheaper, and those cost savings will eventually reach the consumer.

For developers, WebAssembly opens a world of possibility. In today’s operating systems, the user can feel a big difference between applications that need a large client-side runtime (such as video editing tools, or render-heavy games such as Half Life) and applications that are more lightweight and can run entirely on the web (such as Twitter).

Tyler McMullen is the CTO at Fastly. He joins the show to talk about the compilation path, the runtime, and the opportunities of WebAssembly.

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Web Assembly Runtime with Tyler McMullen", + "Episodes Uid": "SED6456080070", + "Episodes Audio File": "afb8e63c53175f6dc6b2a4491cd6dd5e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4ed", + "Episodes ID": "f1768c18-e328-11ea-91a2-f703072a9e29", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_06_MusicEngineering.mp3", + "Episodes Pubdate Date": "2018-09-06", + "Episodes Summary": "

For most of history, a typical musician would learn to play one specific instrument. As synthesizers became available to the public, it became commonplace for a musician to create their own instruments using hardware and software. By the early 2000s, digital audio workstation software allowed a musician with a laptop to have access to the tools of a record producer. These tools changed how music is made, and gave rise to new genres.

Creating electronic music on the computer is a practice much like software engineering. Iteration, modularity, and software architecture skills are required to build a song intelligently. Music engineering also requires working at numerous levels of abstraction: the synthesizer level, the song arrangement level, the mixer level, and the design of melodies.

Dom Kane is a musician and sound engineer who writes music for mau5trap, a label started by deadmau5. He has built software synthesizers, worked with numerous artists as a producer, and written music for film and TV. He joins the show to talk about working as a professional electronic musician. We also talk about the overlap between engineering and the different facets of crafting modern music on the computer.

", + "Episodes Title": "Music Engineering with Dom Kane", + "Episodes Uid": "SED3456550405", + "Episodes Audio File": "30879dd271ca8f59aa0de78be9680f17.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4o6", + "Episodes ID": "f1104552-e328-11ea-91a2-8bc46ceec7f4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_08_AirbnbEngineering.mp3", + "Episodes Pubdate Date": "2018-10-08", + "Episodes Summary": "

Airbnb began in 2008 as a monolithic Rails application serving the simple purpose of listing homes for rental. Over time, the number of listings increased dramatically, as did the number of people who were renting.

With that scale, the Rails app had to be broken into different services, and entire teams were built out to focus on challenges such as pricing, application infrastructure, and search. Surabhi Gupta joined in 2013 to work on the search team, and has worked on different teams at Airbnb over time.

Today she is a director of engineering leading the Homes business for Airbnb, which includes Growth, Search, Hosts, Pricing, and Business Travel. Surabhi has helped scale Airbnb through a hypergrowth period, and joins the show to share those experiences. One distinct area that we spent time on was Airbnb’s search engine. Surabhi formerly worked at Google, and she described how the engineering problem of a search engine for homes differs from a general purpose search engine like Google.

", + "Episodes Title": "Airbnb Engineering with Surabhi Gupta", + "Episodes Uid": "SED6334688666", + "Episodes Audio File": "04ca3ead9f4197b4fb9d309b09f801ec.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3bm", + "Episodes ID": "f52bd3fe-e328-11ea-91a2-57c18fe652ab", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/HackerNoon.mp3", + "Episodes Pubdate Date": "2017-12-19", + "Episodes Summary": "

The New York Times makes most of its money off of subscriptions. Facebook makes its money off of native advertising. Hacker News is funded by Y-Combinator. Each of these business models creates biases in the information that gets promoted on the respective platforms.

This is why I like to know the origin story and the business models behind the publications that I read. Published content is shaped by the profit motive of the publication.

And yet, last month, I repeatedly found myself reading high quality content on a Medium publication that I did not know the origin of: Hacker Noon. Hacker Noon is a popular Medium publication that syndicates curated content written about software.

Let me explain “syndication.” Imagine that I just spent three days on a Medium post about functional programming, and I have zero followers on social media. How can I get people to read awesome post? The answer is syndication. I can submit my Medium post to Hacker Noon. This gives me free distribution, and it gives Hacker Noon free content—a win-win relationship.

But why was it worth it for Hacker Noon to spend time curating content? That syndication process takes time. You have to read through lots of submissions, sometimes you have to send it back to the author to have it edited. And this is all to build a following on Medium. I have not heard of Medium being a profitable platform to build a business.

It’s worth pointing out the difference between Medium and WordPress.

On WordPress, this model of curated syndication has worked to massive success—for example, the Huffington Post and TechCrunch. These businesses make millions of dollars from advertising networks, because they are built on WordPress, and WordPress is an open model.

A publisher on WordPress can install plugins that serve ads from third party providers like Outbrain and Taboola. A WordPress site can also install any kind of data collection scripts, to gather data on visitors, and sell it to the highest bidder.

The lack of third party plugins is the blessing and the curse of Medium.

Because there is no third party ecosystem, reading content on Medium is a beautiful experience. The page loads quickly and predictably. There are no random scripts that are blocking the page as they hog your browser’s resources. When you go to close the page, there is never a popup that asks you to subscribe to a newsletter.

When I read content on Medium, I am not getting slapped across the face with ads for reverse mortgages and açaí berries. I am not being tagged for retargeting. It’s a beautiful experience. But Medium seems like an ecosystem that would not allow for the content syndication business like Hacker Noon.

I wanted to know who was running Hacker Noon, how the business works, and what it says about Medium as a publishing platform.

Hacker Noon turns out to be part of a network of Medium publications called AMI. AMI’s network includes sites like Art + Marketing, Future Travel, and Fit Yourself Club–all of which are distinct syndication platforms. David Smooke is the CEO of AMI, and he joins this episode to explain how his business works, how he has scaled the content syndication business, and why he is betting on Medium. It was a detailed look into the state of online publishing and where it might be headed.

If you don’t read Hacker Noon already, one article to start with that shows off the quality of content is Learn Blockchains By Building One. I interviewed the author of that article, Daniel Van Flymen, and it has been one of the most popular episodes of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Hacker Noon with David Smooke", + "Episodes Uid": "SED9622267249", + "Episodes Audio File": "79978433a9ee4720acfd709ef5596359.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "64e", + "Episodes ID": "ec9578f8-e328-11ea-91a2-b398eed7f15e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_29_FacebookParseAcquisitionwithCharityMajors.mp3", + "Episodes Pubdate Date": "2019-08-29", + "Episodes Summary": "

Parse was a backend-as-a-service company that started in 2011 with the initial focus of making the cloud easier to use for mobile developers. Parse had several novel engineering challenges. In 2011, it was not easy to build on top of AWS, nor was it easy to build within the young mobile ecosystem.

Charity Majors was an early engineer at Parse, and stayed with the company through its acquisition by Facebook. Charity joins the show to discuss her experience at Parse and her reflections on being part of Facebook after the acquisition. Parse was shut down in 2017, which was a disappointing outcome for Charity.

Charity currently works as the CTO of Honeycomb. In a previous episode, Charity gave some background on her career in software, as well as her perspective on modern problems in observability and DevOps. In this episode, Charity tells the story of joining Parse, working through novel engineering problems, and the feeling of being acquired by a company where she did not feel like a great cultural fit.

It is a useful conversation for anyone interested in engineering culture, company philosophy, and the realities of acquisitions–which can be both painful and profitable for the acquired employees.

", + "Episodes Title": "Facebook Parse Acquisition (Part 1) with Charity Majors", + "Episodes Uid": "SED1715235767", + "Episodes Audio File": "1390226041cccfb447feac1a6de03402.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2wn", + "Episodes ID": "f73a8744-e328-11ea-91a2-3b5e46c288bc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SimpleProgrammer.mp3", + "Episodes Pubdate Date": "2017-07-19", + "Episodes Summary": "

Software engineers have a skill set that can be applied to solve problems outside of a codebase. Analytical skills can be used to evaluate investment opportunities. Creative thinking can be used to build businesses. Communication skills can be used to build and enhance relationships.

John Sonmez is a software engineer who created the Simple Programmer, a community of developers who discuss strategies around software, business, and life. He joined me on the show to discuss these topics and others, as well as his new book The Complete Software Developer’s Career Guide.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

SE Radio: John Sonmez, Marketing Yourself and Managing Your Career

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Simple Programmer with John Sonmez", + "Episodes Uid": "SED7705907373", + "Episodes Audio File": "63a3647362cc48a67d6095f6177c0b47.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2mp", + "Episodes ID": "fe7aa6c4-e328-11ea-91a2-6fac453d0fe1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SpringBoot.mp3", + "Episodes Pubdate Date": "2017-04-26", + "Episodes Summary": "

Spring Framework is an application framework for Java and JVM languages. Spring was originally built around dependency injection, but grew to become an entire ecosystem of tools and plugins for Java developers.

Spring was originally released 15 years ago, and since then a lot has changed around application development. For example, many engineers deploy applications to the cloud in microservices architectures. The expectations around frameworks has also changed, with the rise of Django, Ruby on Rails, and NodeJS.

Spring Boot takes an opinionated view of building production-ready Spring applications. By taking an opinionated view, Spring Boot gets engineers up and running faster than the traditional Spring framework. Josh Long is a Spring Developer Advocate at Pivotal and he joins the show to discuss Spring Boot and the history of the Spring Framework.

Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup. We would love to get your feedback on Software Engineering Daily. Please fill out the listener survey, available on softwareengineeringdaily.com/survey.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to download the Spring Boot transcript.

", + "Episodes Title": "Spring Boot with Josh Long", + "Episodes Uid": "SED3194739561", + "Episodes Audio File": "7da02952e6c90a0c0e34de1c3f38733e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3b5", + "Episodes ID": "f53a1842-e328-11ea-91a2-6bb84e5c7444", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ScalaatDuolingo.mp3", + "Episodes Pubdate Date": "2017-12-14", + "Episodes Summary": "

Duolingo is a language learning platform with over 200 million users. On a daily basis millions of users receive customized language lessons targeted specifically to them. These lessons are generated by a system called the session generator.  

Andre Kenji Horie is senior engineer at Duolingo. He wrote about the process of rewriting the session generator, moving from Python to Scala and changing architecture at the same time. In this episode Adam Bell talks with him about the reasons for the rewrite, what drove them to move to Scala and the experience of moving from one technology stack to another.

Rewriting Doulingo’s Engine in Scala

Jobs at Duolingo

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Scala at Duolingo with Andre Kenji Horie", + "Episodes Uid": "SED7156984238", + "Episodes Audio File": "34b5bac35437bfef67d6bfdad5d2ec80.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2au", + "Episodes ID": "0ff5be5c-e329-11ea-91a2-8b889c461864", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/rust_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-11-23", + "Episodes Summary": "

Rust is a systems level language that is built to prevent crashes and eliminate data races. A language like C++ gives you high speed and lots of control, but it is easy to have segfaults, data races, and other problems if you aren’t careful. On this spectrum of control versus safety, we can plot other languages like Java, Go, and Haskell–but none of these languages have the unique feature set of Rust.

Rust’s concurrency model is built on the foundation of ownership–a piece of data can only be owned by a single thing at a time. In today’s interview, Alex Crichton explains ownership, and the other abstractions that give Rust its unique model of concurrency.

", + "Episodes Title": "Rust Concurrency with Alex Crichton", + "Episodes Uid": "SED1958434379", + "Episodes Audio File": "7877dcd315a9779aa64565a7403aa110.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "33b", + "Episodes ID": "f63317e4-e328-11ea-91a2-3b72adc39814", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Usermind.mp3", + "Episodes Pubdate Date": "2017-10-04", + "Episodes Summary": "

A customer engages with a company across a variety of channels–email, Zendesk, Salesforce, online advertising. Unifying those data sources and getting a dashboard into the entire customer experience is the goal of Usermind, a customer engagement hub. If you can get all of that data unified in one place, it creates a tool that salespeople, customer service, and marketing can all look at to see how users are engaging with a company.

Michel Feaster is the CEO of Usermind, and she joins the show to describe how Usermind works and the engineering behind the product. To connect all the different APIs from all those other companies makes this a complicated integration problem, and hearing the Usermind strategy for managing integrations will be useful to anyone listening who is building a product with lots of external API integrations.

Stay tuned at the end of the episode for Jeff Meyerson’s tip about launching a side business: brought to you by Indeed Prime.

If you like listening to this podcast, download the Software Engineering Daily app for iOS and Android to hear all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that. If you don’t like this episode, you can easily find something more interesting by looking at the recommendations in the app.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! The Software Engineering Daily open source community is building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend. If you are interested in contributing, check out github.com/softwareengineeringdaily–or send me an email: jeff@softwareengineeringdaily.com

", + "Episodes Title": "User Management with Michel Feaster", + "Episodes Uid": "SED1547342940", + "Episodes Audio File": "2193ec722b7026addd055c1163c83782.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "59h", + "Episodes ID": "efa1dce4-e328-11ea-91a2-47102e3abb04", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_28_MartinCasado.mp3", + "Episodes Pubdate Date": "2019-01-28", + "Episodes Summary": "

Infrastructure software can be a great business.

An infrastructure software company sells core technology to a large enterprise such as a bank or insurance company. This software has near zero marginal cost and generates a large annuity for the infrastructure software company. Once a bank has purchased your infrastructure software, the bank is likely to renew every year and never remove the software.

Selling infrastructure software is like selling concrete or steel, except the software is cheaper to produce, easier to distribute, and generates an annuity rather than being a one-time sale.

The fundamental economics of enterprise infrastructure software are extremely appealing, and every year more businesses enter the space–but few businesses ever leave. If you are starting an infrastructure software company, you can expect a complex battle for market share. There is no easy trick to get it into the hands of your target customer.

Martin Casado studied computer science at Stanford before founding Nicira, a company that pioneered software-defined networking and virtualization technology. In 2012, Nicira sold to VMware for $1.26 billion. Martin now works as a general partner at Andreessen Horowitz.

Martin writes about the modern strategies of building a successful infrastructure software company. He describes two methods of selling into an enterprise: bottoms-up and top-down.

In a bottoms-up model, engineers within an enterprise start using your product to solve a well-defined problem, such as API management. As more and more employees within the organization start to use your product, you can begin to engage the enterprise about becoming a paying customer for your product. Since the enterprise is already using your product, the sales conversation is much easier.

In the top-down model, you engage the CIO, CEO, or CTO directly and try to convince them that your product is worth paying for. When the senior leadership of a bank buys into your product idea, you can count on that senior leadership to convince their developers to use your product within the bank.

It is a rare occurrence that your infrastructure software company will be able to fit cleanly into either of these models–bottoms-up or top-down. More often, there will be some bottoms-up usage, and some top-down buy-in for your product. But you will have to evangelize the product on all fronts. You will have to convince both the engineers and the senior leadership.

Your product probably won’t speak for itself. You will have to develop expertise in sales, marketing, and consultancy. And in many cases, you might end up in an unending chasm.

The unending chasm describes a mode in which an infrastructure company must function as both a product company and a consultancy. Your consultancy is necessary to integrate your product into the enterprise, and ensure that your software actually gets used. But it reduces the appealing economics of a pure software company.

The unending chasm does not prevent you from being successful. Companies who have had very successful IPOs remain in the unending chasm. But it’s useful to know whether you are heading for an unending chasm–or if you are already in one.

Martin Casado joins the show today for a discussion of product development, software engineering, and go-to-market strategy.

To find all 900 of our episodes, including past episodes with a16z partners, check out the Software Engineering Daily app in the iOS and Android app stores. Whether or not you are a software engineer, we have lots of content about technology, business, and culture. In our app, you can also become a paid subscriber and get ad-free episodes–and you can have conversations with other members of the Software Engineering Daily community.

Image Source

", + "Episodes Title": "Software Chasms with Martin Casado", + "Episodes Uid": "SED6359497909", + "Episodes Audio File": "85d0a46edf3923eb20301a35fcf0359e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "31q", + "Episodes ID": "f685ddbc-e328-11ea-91a2-730d2cf9f560", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DAOHack.mp3", + "Episodes Pubdate Date": "2017-09-11", + "Episodes Summary": "

The Decentralized Autonomous Organization (DAO) was a digital form of venture capital. It was an ambitious idea–to provide a new decentralized business model for organizing corporations on top of the Ethereum blockchain. Few people in the crypto community were opposed to this premise–but the timeline was short, the code requirements were tremendous, and in retrospect, a vulnerability was inevitable.

The DAO launched in May 2016, setting the record for the largest crowdfunding event in history. The following month, the DAO was hacked, millions of dollars of Ether were stolen, and the reverberations of the event were a referendum on how the Ethereum community governs itself.

Matt Leising is a reporter for Bloomberg who has chronicled the DAO in his article The Ether Thief. He continues to follow cryptocurrencies closely, as the Internet of money fractals increasingly into the public consciousness.

If you like this episode, we have done many other shows about cryptocurrencies and their implications. You can check out our back catalog by downloading the Software Engineering Daily app for iOS, where you can listen to all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that.

Errata: Coinbase now supports Bitcoin Cash. 

", + "Episodes Title": "DAO Hack with Matt Leising", + "Episodes Uid": "SED6766401758", + "Episodes Audio File": "a14a40fd432c9d0fca0e102538fb1827.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2x4", + "Episodes ID": "f72bf800-e328-11ea-91a2-93b8134cafed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CNI.mp3", + "Episodes Pubdate Date": "2017-07-24", + "Episodes Summary": "

Containers are widely used in projects that have adopted Docker, Kubernetes, or Mesos. Containers allow for better resource isolation and scalability. With all of the adoption of containers, companies like Red Hat, Google, and CoreOS are working on improved standards within the community.

Standards are important to this community because of its pace of growth and the number of concurrent projects. If you heard our recent episode about the Linux Kernel’s open source governance, you know that having some rules in place will help encourage the right kind of creativity to thrive.

In the world of containers, networking is not well addressed as it is highly environment specific. The Container Networking Interface is an effort to add specifications around how networks of containers can form.

Dan Williams is an engineer at Red Hat. In today’s episode, he explores the ideas behind the container networking interface, which gives insights into how the broader community of cloud native technologies is evolving as a whole.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Container Networking with Dan Williams", + "Episodes Uid": "SED9523771275", + "Episodes Audio File": "03ada588f2174a6a1a256877701f024b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5a6", + "Episodes ID": "ef8fc310-e328-11ea-91a2-2382965688e9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_31_MartinFord.mp3", + "Episodes Pubdate Date": "2019-01-31", + "Episodes Summary": "

Artificial intelligence is reshaping every aspect of our lives, from transportation to agriculture to dating. Someday, we may even create a superintelligence–a computer system that is demonstrably smarter than humans. But there is widespread disagreement on how soon we could build a superintelligence. There is not even a broad consensus on how we can define the term “intelligence”.

Information technology is improving so rapidly we are losing the ability to forecast the near future. Even the most well-informed politicians and business people are constantly surprised by technological changes, and the downstream impact on society. Today, the most accurate guidance on the pace of technology comes from the scientists and the engineers who are building the tools of our future.

Martin Ford is a computer engineer and the author of Architects of Intelligence, a new book of interviews with the top researchers in artificial intelligence. His interviewees include Jeff Dean, Andrew Ng, Demis Hassabis, Ian Goodfellow, and Ray Kurzweil.

Architects of Intelligence is a privileged look at how AI is developing. Martin Ford surveys these different AI experts with similar questions. How will China’s adoption of AI differ from that of the US? What is the difference between the human brain and that of a computer? What are the low-hanging fruit applications of AI that we have yet to build?

Martin joins the show to talk about his new book. In our conversation, Martin synthesizes ideas from these different researchers, and describes the key areas of disagreement from across the field.

To find all 900 of our old episodes, including past episodes with authors and artificial intelligence researchers, check out the Software Engineering Daily app in the iOS and Android app stores. Whether or not you are a software engineer, we have lots of content about technology, business, and culture. In our app, you can also become a paid subscriber and get ad-free episodes–and you can have conversations with other members of the Software Engineering Daily community.

", + "Episodes Title": "Architects of Intelligence with Martin Ford", + "Episodes Uid": "SED4274232550", + "Episodes Audio File": "41d90ad4a8298caef181862dea8ea564.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5lh", + "Episodes ID": "ee8f3d42-e328-11ea-91a2-27123f41f082", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_12_HaseebMeetup.mp3", + "Episodes Pubdate Date": "2019-04-12", + "Episodes Summary": "

RECENT UPDATES:

FindCollabs $5000 Hackathon Ends Saturday April 15th, 2019

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

Haseeb Qureshi is an entrepreneur and investor. As a teenager, Haseeb played poker professionally through the online poker bubble. His path from poker to software entrepreneurship has been explored in previous episodes.

In 2007, Haseeb and I met at an online poker table. As we battled each other for thousands of dollars, Haseeb and I realized we shared an affinity for obnoxious screen names, obnoxious online avatars, and the city of Austin, Texas. We were both living in the city, and met each other in the real world.

In our earliest days, Haseeb and I were not friends. It was a strange time–we were disembodied minds, drifting on the Internet, attached mostly to the fluctuating balances of our Full Tilt Poker and Pokerstars accounts. This was not a time for friendship–it was a time for ruthless, modern competition.

Throughout the history of poker, alliances have always been fickle. And online, backstabbing and deception was an art that had been barely explored. Any true friendship was a missed opportunity to exploit a competitor.

The duplicity of the online poker world knew no limits, and our sheltered, posh existence of teenagers with great parents, food on the table every evening, and no reason to worry became shattered by the daily tumult of complete financial instability.

Online poker was in a bubble. In the early days of a bubble, success comes easy. You have to be a fool to fail. When a bubble pops, the ocean washes back to the sea, and we see who is left without any clothing.

The poker bust wiped me out. Not just financially, but emotionally. In a month, I lost hundreds of thousands of dollars, and I lost my identity. After doing nothing but playing poker for years, what was I left with? What durable skills had I developed? What friends did I have to turn to? What was my ideology? What was my vision for my own future?

As I plummeted into despair, Haseeb rose like a meteor through the world of heads up poker, thriving on the rise in popularity of pot limit Omaha, a game whose theoretical complexity suited Haseeb better than the rudimentary game of no limit hold’em. The bigger the stacks, the bigger the decision trees, and the bigger the decision trees, the more edge Haseeb had over his opponents.

As a professional poker player, regardless of whether you succeed or fail, the banality of what you are actually doing eventually catches up to you. The best players are able to put an athletic framing to the game. Yes, you are competing on a zero sum basis, with a 52 card deck that was invented last century. Yes, your innovation is measured in the smallest increment of invention. But in some ways, that is the beauty of the game. We don’t need a revolution in the game of basketball, because to appreciate the dynamic of basketball is to appreciate the dynamic of humans. And the same can be said of poker.

Unfortunately, the successful online poker player must eventually have their own reality shattered. Because to be a successful poker player, you must be rigorous and critical. You will eventually be forced to step back and say: “what is this thing I’m doing every day? How have I become hooked to a screen? I don’t know how that screen works. What are these numbers? Are they fabricated? How do they control my emotions so thoroughly? Who is running this thing?”

Haseeb grew tired of poker. He wrote a book about the game to memorialize his thoughts, then abandoned it. He studied philosophy and literature, searching for something new in the historical musings of humanity. He traveled Europe, working as a farmer to reconnect with the physical world. He discovered the Effective Altruism movement.

Finding no solace in his poker spoils, Haseeb gave away most of his money and started from scratch. As he rebuilt himself, he found software engineering and charted a path to San Francisco, where we reconnected.

In this episode, Haseeb joins me for a discussion of software, philosophy, poker, and the nature of bubbles. Indeed, Haseeb and I have now lived through four major bubbles: dot coms, poker, the 2008 financial crisis, and the crypto bubble. Throughout these bubbles, the mediums change but never does the message: human beings are deeply irrational, tribalistic, and emotional.

", + "Episodes Title": "Bubbles with Haseeb Qureshi", + "Episodes Uid": "SED6238595199", + "Episodes Audio File": "c7c82b32a1606a6cd64d4fe39a9ffaa7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5h7", + "Episodes ID": "eede8a14-e328-11ea-91a2-cf73f322fa8b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_20_ElasticSearchProsandCons.mp3", + "Episodes Pubdate Date": "2019-03-20", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Bol.com is the biggest e-commerce company in the Netherlands and Belgium. For 20 years, Bol has been developing its software architecture, which includes a variety of services and databases, and a mix of physical and cloud infrastructure.

For an ecommerce company, the search engine is critical for allowing customers to find the products they are looking for. But search also has many applications for internal systems. A search engine is a database with a query engine, and internal application developers want to build on top of that database.

Volkan Yazici is an engineer at Bol.com specializing in search and the author of the blog post Using ElasticSearch as the Primary Data Store. In his post, Volkan describes the process of scaling ElasticSearch to fit the use cases of both internal and external users at a large ecommerce company.

Volkan joins the show to discuss how search infrastructure at scale can require a carefully architected data pipeline in order to propagate changes to a large data set to a search index.

", + "Episodes Title": "ElasticSearch at Scale with Volkan Yazici", + "Episodes Uid": "SED4926400124", + "Episodes Audio File": "6b52bca6ebdd5d2b5e100aa787b505c7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 603, + "Episodes ID": "ecf42164-e328-11ea-91a2-3b498b04413b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_01_Hackathons.mp3", + "Episodes Pubdate Date": "2019-08-01", + "Episodes Summary": "

A hackathon is an organized event where participants work together to build a product or tool. Hackathons are about creativity, learning, and exploration. A developer that is participating in a hackathon is often working on something that is outside of their normal day-to-day focus. 

Hackathons can provide significant value to the participants. Hackathons have led to friendships, new companies, and newly developed confidence that can be critical to a developer who feels uncertain in their ability to launch their own projects.

Jonathan Gottfried is a co-founder of Major League Hacking, an official student hackathon league that powers invention competitions. Major League Hacking is a B corporation that is focused on improving the education and community of technology leaders, entrepreneurs, and young hackers.

Jon joins the show to discuss hackathons–and how he has built and scaled an organization that is devoted to creating systematically successful hackathon experiences.

", + "Episodes Title": "Hackathons with Jonathan Gottfried", + "Episodes Uid": "SED3508922826", + "Episodes Audio File": "dd070315ae8f4a3cfb1120af73968090.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2gd", + "Episodes ID": "08926980-e329-11ea-91a2-bb7ba58f685b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/giphy_edited.mp3", + "Episodes Pubdate Date": "2017-02-06", + "Episodes Summary": "

Giphy is a search engine for gifs, the short animated graphics that we see around the Internet. Giphy is also a creative platform where people create new gifs.

Every search engine requires the construction of a search index, which is a data structure that responds to search queries efficiently. Since Giphy is a search engine for graphics, there is almost no text inherently associated with the each document. Giphy uses a pipeline of different labeling techniques in order to make a gif indexable by the search engine.

In my conversation with Giphy CTO Anthony Johnson, we discuss how to scale a search engine, why Giphy needs to build new techniques for image processing, how human labeling for machine learning is evolving, and the future of Giphy–both as a creative medium and an advertising platform.

This was an exciting and wide-reaching interview.

", + "Episodes Title": "Giphy Engineering with Anthony Johnson", + "Episodes Uid": "SED3590639820", + "Episodes Audio File": "32c27822f0631e3c2a63b003ccc6621f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7cu", + "Episodes ID": "e8cd7fa4-e328-11ea-91a2-836246c4fbe1", + "Episodes Original URL": "https://sd-profile-pictures.s3-us-west-2.amazonaws.com/adfree/dataintensive_edited_fixed_adfree.mp3", + "Episodes Pubdate Date": "2020-06-23", + "Episodes Summary": "

Originally published May 2, 2017. We are taking a few weeks off. We’ll be back soon with new episodes.

A new programmer learns to build applications using data structures like a queue, a cache, or a database. Modern cloud applications are built using more sophisticated tools like Redis, Kafka, or Amazon S3. These tools do multiple things well, and often have overlapping functionality. Application architecture becomes less straightforward.

The applications we are building today are data-intensive rather than compute-intensive. Netflix needs to know how to store and cache large video files, and stream them to users quickly. Twitter needs to update user news feeds with a fanout of the president’s latest tweet. These operations are simple with small amounts of data, but become complicated with a high volume of users.

Martin Kleppmann is the author of Data Intensive Applications, an O’Reilly book about how to use modern data tools to solve modern data problems. His book includes high-level discussions about architectural strategy, and lower level discussions like how leader election algorithms can create problems for a data intensive application.

", + "Episodes Title": "Data Intensive Applications with Martin Kleppman (Summer Break Repeat)", + "Episodes Uid": "SED1846711377", + "Episodes Audio File": "f66a09a1adfa91f1440fbceca6fb1890.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3er", + "Episodes ID": "f4b4a734-e328-11ea-91a2-4b6ca4c542e9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_19_ConduitProxy.mp3", + "Episodes Pubdate Date": "2018-01-19", + "Episodes Summary": "

Oliver Gould worked at Twitter from 2010 to 2014. Twitter’s popularity was taking off, and the engineering team was learning how to scale the product.

During that time, Twitter adopted Apache Mesos, and began breaking up its monolithic architecture into different services. As more and more services were deployed, engineers at Twitter decided to standardize communications between those services with a tool called a service proxy.

A service proxy provides each service with features that every service would want: load balancing, routing, service discovery, retries, and visibility. It turns out that lots of other companies wanted this service proxy technology as well, which is why Oliver left Twitter to start Buoyant, a company that was focused on developing software around the service proxy–and eventually the service mesh.

If you are unfamiliar with service proxies and service mesh, check out our previous shows on Linkerd, Envoy, and Istio.

Kubernetes is often deployed with a service mesh. A service mesh consists of two parts: the data plane and the control plane.

The “data plane” refers to the sidecar containers that are deployed to each of your Kubernetes application pods. Each sidecar has a service proxy. The “control plane” refers to a central service that aggregates data from across the data plane and can send communications to the service proxies sitting across that control plane.

The Linkerd service mesh was built in Java, and the project started before Kubernetes had become the standard for container orchestration. More recently, Buoyant built Conduit, a service mesh built using Rust and Go.

In this episode, we explore how to design a service mesh and what Oliver learned in his experience building Linkerd and Conduit.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Service Mesh Design with Oliver Gould", + "Episodes Uid": "SED3536059087", + "Episodes Audio File": "f124677d01c9318bffdb0db6555f3357.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 324, + "Episodes ID": "f67747ac-e328-11ea-91a2-2fad0bfd31a6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Visual_Search.mp3", + "Episodes Pubdate Date": "2017-09-15", + "Episodes Summary": "

If I have a picture of a dog, and I want to search the Internet for pictures that look like that dog, how can I do that?

I need to make an algorithm to build an index of all the pictures on the Internet. That index can define the different features of my images. I can find mathematical features in each image that describe that image. The mathematical features can be represented by a matrix of numbers. Then I can run the same algorithm on the picture of my dog, which will make another matrix of numbers. I can compare the matrix representing my dog picture to the matrices of all the pictures on the internet.

This is what Google and Facebook do–and we covered this topic in our episode about similarity search a few weeks ago. Today, we evaluate a similar problem: searching images within Squarespace. Squarespace is a platform where users can easily build their own website for blogging, e-commerce, or anything else.

Neel Vadoothker is a machine learning engineer at Squarespace, and he joins the show to talk about how and why he built a visual similarity search engine.

If you like this episode, we have done many other shows about machine learning. You can check out our back catalog by going to softwareengineeringdaily.com or by downloading the Software Engineering Daily app for iOS, where you can listen to all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that.

", + "Episodes Title": "Visual Search with Neel Vadoothker", + "Episodes Uid": "SED6399947332", + "Episodes Audio File": "c393a63ccd60362e8d0790dadc9e57b2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5eg", + "Episodes ID": "ef24ba2a-e328-11ea-91a2-f3424b24636c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_04_Starkware.mp3", + "Episodes Pubdate Date": "2019-03-04", + "Episodes Summary": "

Computational integrity is a property that is required for financial transactions on the Internet. Computational integrity means that the output of a certain computation is correct.

If I deposit money into my bank, my bank sends me a number that represents the new balance in my account. I assume that the number they have sent me is correct. The bank could be lying to me–maybe this bank is not actually trustworthy. But I use a bank with a good reputation. If the bank stole money from its users, it would quickly go out of business. Therefore, I feel safe by trusting a bank with my money, because the bank needs to maintain its reputation.

The problem with reputation-based systems is that they are opaque. It’s not easy for us to audit the bank and prove the bank actually has the money that it claims to have. Most of the time, the reputation-based systems work fine. But occasionally, we have catastrophic events–think of the 2008 financial crisis, or the Bernie Madoff financial scandal.

These circumstances would have been avoided if the financial institutions could have been continuously audited for their solvency.

With blockchains and cryptocurrencies, we now have tools that allow us to maintain computational integrity without the opaque systems of reputation. We no longer have to trust a central authority–we can verify computational integrity with math.

Eli Ben-Sasson is a co-founder and chief scientist at StarkWare Industries, a company that is bringing zero-trust technology to market. Implementations of zero-trust technology include zk-STARKs, zk-SNARKs, and bulletproofs. StarkWare is focused on the application of zk-STARKs, which can be used to improve scalability and privacy.

Eli joins the show to discuss the topic of computational integrity, and how STARKs can be used to provide scalable, secure infrastructure to blockchain applications.

", + "Episodes Title": "StarkWare: Transparent Computational Integrity with Eli Ben Sasson", + "Episodes Uid": "SED8957916841", + "Episodes Audio File": "cd4d8323c53f5c881d5a5dee5e0d7500.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3pl", + "Episodes ID": "f3496b5a-e328-11ea-91a2-33efa9492716", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_30_EpicenterBitcoin.mp3", + "Episodes Pubdate Date": "2018-04-30", + "Episodes Summary": "

Podcasting about cryptocurrencies is a strange occupation. You get emails all the time from companies doing a token sale that you would never want to be affiliated with. You get angry tweets from anonymous Twitter accounts that are on one side of the Bitcoin scaling debate. You get to interview extreme personalities, and the technical discussions can be highly educational.

Brian Fabian Crain started the Epicenter podcast four years ago. Podcasting about cryptocurrencies allows a podcaster to report on a wide range of areas: economics, software, philosophy–and the stories within the blockchain world itself. Epicenter is one of my favorite podcasts about cryptocurrencies because Brian is always prepared enough to ask sophisticated questions.

In this episode, we talked about ICOs–when does an ICO make sense? It seems that many token economies could function just as well without a token involved. We discussed the scaling approaches of Bitcoin and Ethereum–why are these two blockchains taking very different approaches to their scaling plans? And we talked about Chorus, the company that Brian founded to build infrastructure for proof-of-stake cryptocurrencies.

I enjoyed talking to Brian about all these different subjects, and look forward to having him on again in the future.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Epicenter Cryptocurrencies with Brian Fabian Crain", + "Episodes Uid": "SED7288907437", + "Episodes Audio File": "0288e0a4bc21dc63d0f0641b31954df9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2kj", + "Episodes ID": "01da24a2-e329-11ea-91a2-9b07ccad937f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/qanda_edited_fixed.mp3", + "Episodes Pubdate Date": "2017-04-04", + "Episodes Summary": "

In this episode, I gathered questions from listeners in our Slack channel and Twitter feed. The questions I answered include:

We always want more feedback and questions. Please email me, join Slack, and fill out our survey!

", + "Episodes Title": "Listener Q&A", + "Episodes Uid": "SED7991996642", + "Episodes Audio File": "a91f3e83f2da2fb7adb35a3bdb94dd9a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3d8", + "Episodes ID": "f4c337d6-e328-11ea-91a2-9bf76520e4ff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_16_MulticloudKubernetes.mp3", + "Episodes Pubdate Date": "2018-01-16", + "Episodes Summary": "

In the last four years, CoreOS has been at the center of enterprise adoption of containers. During that time, Brian Harrington (or “Redbeard”) has seen a lot of deployments. In this episode, Brian discusses the patterns he has seen among successful Kubernetes deployments–and the pitfalls of the less successful.

How should you manage configuration? How can you avoid IP address overlap between containers? How should you log and monitor your Kubernetes cluster–and whose responsibility is it to set all that stuff up?

Brian also discusses the motivation for multi-cloud deployments, and how to implement multi-cloud Kubernetes.

CoreOS offers a distributed systems management tool called Tectonic, which uses Kubernetes for container orchestration. In a time where there are lots of options to choose from when it comes to managed Kubernetes providers, it was great to hear Brian describe some of the architectural decisions for building Kubernetes into Tectonic.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kubernetes Operations with Brian Redbeard", + "Episodes Uid": "SED3001075259", + "Episodes Audio File": "5996003669310a5665e3b75585754cb1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ow", + "Episodes ID": "fcfe2aaa-e328-11ea-91a2-b3294c8d5d4b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/wapo_edited_2.mp3", + "Episodes Pubdate Date": "2017-05-04", + "Episodes Summary": "

The Washington Post was acquired by Amazon CEO Jeff Bezos in 2013. Since then, the newspaper has started thinking more like a software company, opting to build new software rather than buy off-the-shelf third party solutions.

Arc Publishing is a CMS built by The Washington Post to produce and display content. When you visit washingtonpost.com, you are viewing a site built with Arc Publishing. The Washington Post has also brought its advertising technology in-house.

Jarrod Dicker is the head of commercial product and technology at The Washington Post. He joins the show to discuss the transformation that has occurred since Bezos purchased the company. We also explore the problems in digital advertising that have been covered in recent episodes of Software Engineering Daily.

Thanks to listener Mani Gandham for introducing me to Jarrod, and if you have a suggestion for a guest you want to hear, please send me an email.

If you are interested in hosting a show for Software Engineering Daily, we are looking for engineers, journalists, and hackers who want to work with us on content. It is a paid opportunity. Go to softwareengineeringdaily.com/host to find out more.

The Software Engineering Daily store is now open if you want to buy a Software Engineering Daily branded t-shirt, hoodie, or mug and support the show. Let’s get on with the show. Go to softwareengineeringdaily.com/store.

", + "Episodes Title": "Washington Post Engineering with Jarrod Dicker", + "Episodes Uid": "SED6930254309", + "Episodes Audio File": "ae9940c4c209c025c4d5b4dae90e1cc2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48u", + "Episodes ID": "f1b86c50-e328-11ea-91a2-d7228cf4ab0d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_15_WalletSecurity.mp3", + "Episodes Pubdate Date": "2018-08-15", + "Episodes Summary": "

Cryptocurrency security is a concern to anyone who has a significant amount of money in the form of Bitcoin, Ethereum, or other crypto assets. Most Bitcoin is held in either a Bitcoin wallet or a Bitcoin bank.

Your Bitcoin holdings are recorded on a public ledger. You access these holdings by authenticating with your private key. A Bitcoin wallet could be described more accurately as a Bitcoin keyring. Securing your Bitcoin wallet is about securing that private key. Just as there are many different ways to secure any individual piece of text, there are many ways to secure a Bitcoin private key.

A Bitcoin “bank” is a term that can be used to describe institutions such as Coinbase. Coinbase takes the technology of the Bitcoin wallet and wraps it in additional layers of security, identity, and failover that we associate with banks and large technology companies.

By using a Bitcoin bank, you sacrifice the autonomy of managing your own private key. On the bright side, you don’t have to manage your own private key. If you lose your Coinbase password, there are plenty of ways to recover it. A Bitcoin bank gives you the downsides and the upsides of working with a centralized service provider.

Jameson Lopp is a cypherpunk and cryptocurrency engineer at Casa. Casa is a company that is building long-term cryptocurrency storage and secure key infrastructure. In this episode, we explore how Bitcoin wallets work, how to secure them, the common threats, scams and hacking attempts of Bitcoin, and what he is working on at Casa.

", + "Episodes Title": "Casa: Crypto Wallet Security with Jameson Lopp", + "Episodes Uid": "SED2006113191", + "Episodes Audio File": "0aee4034d85426eba0f6990db7d64ff4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2fs", + "Episodes ID": "0978d370-e329-11ea-91a2-2743fd917ef4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/robotics_edited.mp3", + "Episodes Pubdate Date": "2017-01-27", + "Episodes Summary": "

Many elderly people live with unhealthy levels of isolation. Social isolation is a problem for anybody, but younger people can use technology to alleviate their isolation with tools like Skype and Facebook. How can we bridge the generational gap and give elderly people access to the same technological tools that younger people find easy to use?

Voice interfaces are an important new medium for communicating with computers. Amazon and Google are at the forefront of the voice interface movement, but many other devices are emerging. One of these devices is Elliq, from Intuition Robotics.

Elliq consists of a microphone voice interface that sits on a table next to a small tablet computer. An elderly person can talk to the voice interface and have it start a voice call with someone on Skype, or see new Facebook photos or YouTube videos.

The discussion of Elliq’s hardware is as interesting as that of its backend software. As Itai Mendelsohn of Intuition Robotics explains, Elliq got to market very quickly as a result of the company’s adoption of high-level managed services, like Firebase and Google’s managed machine learning.

ELLIQ – The active aging companion

", + "Episodes Title": "Robots for the Elderly with Itai Mendelsohn", + "Episodes Uid": "SED7200903799", + "Episodes Audio File": "3ebdf9b1adf5b2d04f93659e5a2131e0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2v2", + "Episodes ID": "f75a72de-e328-11ea-91a2-37258bdb32ce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Shippable.mp3", + "Episodes Pubdate Date": "2017-07-11", + "Episodes Summary": "

Software deployment evolves over time. In the 90s, a “deployment” might have meant issuing a new edition of your software via CD-ROM. Today, a deployment is often a multi-stage process. A new software build will undergo automated unit tests and integration tests, before being deployed to users.  The deployment might only go out to a small percentage of total users initially, with that percentage going up as the deployment proves not to have bugs.

Avi Cavale is the CEO of Shippable, a platform for DevOps. In this episode, we discussed deployments in the context of containers, including a discussion of what has become easier: microservices, feature flagging, and continuous delivery. He also discussed his experience building Shippable.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Deployment with Avi Cavale", + "Episodes Uid": "SED7756089330", + "Episodes Audio File": "3aba81684f9d6cfbe54caeac7227c01d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 278, + "Episodes ID": "13ef8eac-e329-11ea-91a2-3fb9c13a75b6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/scikit_learn-edited.mp3", + "Episodes Pubdate Date": "2016-09-27", + "Episodes Summary": "

Scikit-learn is a set of machine learning tools in Python that provides easy-to-use interfaces for building predictive models. In a previous episode with Per Harald Borgen about Machine Learning For Sales, he illustrated how easy it is to get up and running and productive with scikit-learn, even if you are not a machine learning expert.
\nSrini Kadamati hosts today’s show and interviews Andreas Mueller, a core committer to scikit-learn. Srini and Andreas discuss the background and implementation of scikit-learn and walk through some prototypical workflows for using it.

", + "Episodes Title": "Scikit-learn with Andreas Mueller", + "Episodes Uid": "SED1465423874", + "Episodes Audio File": "0cb3d3045c4e836606b914f54ad90f4a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2dt", + "Episodes ID": "0c8e89a6-e329-11ea-91a2-eb0929cfe679", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/breakingintostartups_edited.mp3", + "Episodes Pubdate Date": "2017-01-02", + "Episodes Summary": "

Many people find themselves going down a career path that does not bring them satisfaction. A lawyer finds himself constantly working cases he doesn’t care about. A student in medical school gets completely burned out from hospital bureaucracy. An investment banker no longer finds joy in the accounting statements that she used to enthusiastically study.

Startups offer a different career path. Within a startup, an employee can often find creativity, limited bureaucracy, and highly variable reward structures. These ingredients make the world of startups both refreshing and intimidating to someone who feels stuck in a career that no longer gives them joy.

Breaking Into Startups is a podcast about people coming from non-traditional backgrounds and making their way into startups. Breaking Into Startups is run by Artur and Timur Meyster and Ruben Harris, who join me for a conversation about how they migrated from more traditional careers to startups–and how many other people are doing the same.

", + "Episodes Title": "Breaking Into Startups", + "Episodes Uid": "SED2255003743", + "Episodes Audio File": "c94f74e3924b868c2c02f848a2b27213.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "15h", + "Episodes ID": "27eaddc6-e329-11ea-91a2-b30ad9dbc80e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/tessel_Edited.mp3", + "Episodes Pubdate Date": "2015-12-21", + "Episodes Summary": "

Tessel is an open-source microcontroller that is programmable in JavaScript and compatible with Node.js.

Kelsey Breseman is a hardware engineer and Steering Committee Member on the Tessel Project.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "JavaScript on Hardware with Kelsey Breseman", + "Episodes Uid": "SED9241863364", + "Episodes Audio File": "6a3543cf4f6002928de65793732867de.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6n1", + "Episodes ID": "ead2e262-e328-11ea-91a2-c75c66e233f4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_24_GitlabStrategy.mp3", + "Episodes Pubdate Date": "2020-01-24", + "Episodes Summary": "

The word “DevOps” has a different definition depending on who you ask. 

For some people, it is about the process of managing and releasing code. It can involve container management and server orchestration. It can involve infrastructure-as-code, and safer configuration management. In addition to a set of technologies, DevOps can be seen as a management concept that describes agile practices, and breaking down communication barriers between different teams.

One thing that most software companies have decided is that whatever DevOps is, we want it. We want to release more software, we want to do it faster, and we want to do it safer. We want streamlined communication between management and engineering. We want a full understanding of the “value chain” of software.

Despite the elusiveness of a single description for what DevOps is, GitLab can credibly describe itself as a tool that satisfies the DevOps needs of most enterprises. GitLab started as an open source version control management system based on Git. It has expanded into products that include continuous integration, security, issue tracking, and monitoring. 

The trajectory of GitLab into such a large platform is something that nobody anticipated. The best explanation for how it happened is that it is the downstream result of an engineer within GitLab deciding that the code hosting product needed to have a continuous integration product bundled with it as an option for a tightly coupled, unified workflow.

Today, there are many enterprises trying to make a big set of changes to their development practices. The world is consolidating around Git for version control and Kubernetes for container management. Almost every enterprise is figuring out a “cloud strategy”. Every team wants to have continuous integration, and they want it to have some security products paired with that release workflow in a popular, vaguely defined set of practices known as “DevSecOps”.

With so many changes coming to enterprises, it turns out that many of these enterprises just want some sane defaults. When GitLab came to market with a bundled CI and code hosting product, the company discovered that the customers were very happy to have integrated tools that worked well out of the box. This was in stark contrast to the years of NxN tooling integration that an enterprise would have to make to stitch together their broad range of carefully selected tools.

Sid Sibrandij is the CEO of GitLab, and he joins the show for a conversation about how GitLab arrived at its product development strategy. In a previous episode, Sid discussed some of the core features and history of GitLab. Today’s show expands on many of the subjects we explored previously. We also had a spirited discussion of the modern nature of work, and how GitLab’s unique culture and fully remote team have evolved as the company has scaled.

", + "Episodes Title": "GitLab Strategy with Sid Sibrandij", + "Episodes Uid": "SED4422309520", + "Episodes Audio File": "de2da28756b1f758eefa37c43ecd7e1c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7hk", + "Episodes ID": "e84c2fc6-e328-11ea-91a2-13a175d8a010", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_30_Forem.mp3", + "Episodes Pubdate Date": "2020-07-30", + "Episodes Summary": "

Dev.to has become one of the most popular places for developers to write about engineering, programming languages, and everyday life. For those who have not seen it, DEV is like a cross between Twitter and Medium, but targeted at developers. The content on DEV ranges from serious to humorous to technically useful.

DEV contains a set of features which appeal to a developer community, such as the ability to embed code snippets in a post, but for the most part the entire app is generalizable to other types of communities. Hence, the motivation for “Forem”. Forem is an open source project to make it possible to spin up instances of communities that are like DEV, but for other communities such as mixed martial arts, or doctors.

Ben Halpern is the creator of DEV and Forem, and he joins the show to talk about the DEV Community and his long-term goals for what the DEV team is building.

", + "Episodes Title": "DEV and Forem with Ben Halpern", + "Episodes Uid": "SED4223225221", + "Episodes Audio File": "8f1bee7c63d5ca87adf687eb66ddc098.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ka", + "Episodes ID": "e63c264a-e8c9-11ea-9bc1-6b76c2bdfb93", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_27_Anduril.mp3", + "Episodes Pubdate Date": "2020-08-27", + "Episodes Summary": "

Anduril is a technology defense company with a focus on drones, computer vision, and other problems related to national security. It is a full-stack company that builds its own hardware and software, which leads to a great many interesting questions about cloud services, engineering workflows, and management.

Gokul Subramanian is an engineer at Anduril, and he joins the show to share his knowledge of how Anduril operates and what the company has built.

", + "Episodes Title": "Anduril Engineering with Gokul Subramanian", + "Episodes Uid": "SED1718128074", + "Episodes Audio File": "63dc1fa7a79da8d043f24303d77ca12d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "27f", + "Episodes ID": "13aeb7e2-e329-11ea-91a2-bf8f533c993d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Remote_Work_Edited.mp3", + "Episodes Pubdate Date": "2016-09-29", + "Episodes Summary": "

After nine years at Microsoft, Scott Berkun left to become an author. One of his books on project management was read by Matt Mullenweg, the creator of the WordPress blogging tool that runs a large percentage of the internet (including Software Engineering Daily). Scott became friends with the WordPress founder, who is also the CEO of Automattic, a company that sells WordPress hosting and support.

Around that time, Automattic was run as a completely flat company. Everyone reported to Matt. This was unsustainable, and eventually Matt decided that Automattic should try management, and he convinced Scott to take a break from his writing career to return to the world of software engineering as Automattic’s first manager.

Scott accepted the role under the condition that he could write a book about the experience, and the result of that agreement is “The Year Without Pants: WordPress.com and the Future of Work”, which is a brilliant depiction of what it is like to work at a completely remote software company.

Scott joins the show today to talk about his book and his career journey–from Microsoft, to writing, to WordPress, and back to writing. He also shares his thoughts on the workplace dynamics that we spend our days in at software companies.

", + "Episodes Title": "Remote Work with Scott Berkun", + "Episodes Uid": "SED6152113204", + "Episodes Audio File": "2a7a500d4bbb241b0dd660e656e51aa2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6dw", + "Episodes ID": "eb94d7b4-e328-11ea-91a2-5fe376a36bd5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_15_DagsterwithNickSchrock.mp3", + "Episodes Pubdate Date": "2019-11-15", + "Episodes Summary": "

Data engineering is difficult. 

Companies want to be able to maximize the value they get from their large data sets, but there are so many steps required for deriving that value that most companies feel like they are always far behind the ideal state of where they could be. 

The cloud makes it cheap to save data. Tools like Spark and Snowflake give us usable APIs for simplifying the data processing. Workflow engines like Airflow help us visualize a complex execution path of a data pipeline. With all of this tooling, why is it so hard to make use of our data?

Nick Schrock is the creator of Dagster, an open source system for building modern data applications. Nick is also the CEO of Elementl, a company that he is building around Dagster. Before creating Dagster, Nick worked at Facebook, where he co-created GraphQL. 

Nick returns to the show to discuss modern data engineering, and why it continues to be so difficult for engineers to be productive with their data.

", + "Episodes Title": "Dagster with Nick Schrock", + "Episodes Uid": "SED6567462598", + "Episodes Audio File": "a9a77a1191be7d87184ab46046c2e183.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "21g", + "Episodes ID": "1a301570-e329-11ea-91a2-5f5ee456d895", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Weave_Edited.mp3", + "Episodes Pubdate Date": "2016-07-01", + "Episodes Summary": "

Twenty years ago, Bill Joy talked about the eight fallacies of distributed computing–these are things such as “the network is reliable”, and “latency is zero”, and “bandwidth is infinite”, and these fallacies are even more relevant today. With the popularity of Docker containers, the networks of distributed systems that we deal with have become even more complex, and with this growing complexity comes new problems and new fallacies.
\nWeaveWorks is a company building a simple, reliable way to manage containers and microservices. The CEO of Alexis Richardson joins the show today to discuss how Weave uses convergent replicated data types to manage distributed systems. The use of the CRDT data structure is in contrast to the use of Paxos or Raft to algorithmically manage our distributed systems. Our conversation also touches on the Cloud Native Computing Foundation, which is similar to the Apache Foundation, but for cloud native application technologies.

", + "Episodes Title": "Container Management with Alexis Richardson", + "Episodes Uid": "SED2936263109", + "Episodes Audio File": "03099e58c9f533e131b9c6933759f0f2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ra", + "Episodes ID": "ea8d4e28-e328-11ea-91a2-dfa014da7045", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_13_AnyscaleIonStoica.mp3", + "Episodes Pubdate Date": "2020-02-13", + "Episodes Summary": "

Machine learning applications are widely deployed across the software industry. 

Most of these applications used supervised learning, a process in which labeled data sets are used to find correlations between the labels and the trends in that underlying data. But supervised learning is only one application of machine learning. Another broad set of machine learning methods is described by the term “reinforcement learning.”

Reinforcement learning involves an agent interacting with its environment. As the model interacts with the environment, it learns to make better decisions over time based on a reward function. Newer AI applications will need to operate in increasingly dynamic environments, and react to changes in those environments, which makes reinforcement learning a useful technique.

Reinforcement learning has several attributes that make it a distinctly different engineering problem than supervised learning. Reinforcement learning relies on simulation and distributed training to rapidly examine how different model parameters could affect the performance of a model in different scenarios.

Ray is an open source project for distributed applications. Although Ray was designed with reinforcement learning in mind, the potential use cases go beyond machine learning, and could be as influential and broadly applicable as distributed systems projects like Apache Spark or Kubernetes. Ray is a project from the Berkeley RISE Lab, the same place that gave rise to Spark, Mesos, and Alluxio.

The RISE Lab is led by Ion Stoica, a professor of computer science at Berkeley. He is also the co-founder of Anyscale, a company started to commercialize Ray by offering tools and services for enterprises looking to adopt Ray. Ion Stoica returns to the show to discuss reinforcement learning, distributed computing, and the Ray project.

If you enjoy the show, you can find all of our past episodes about machine learning, data, and the RISE Lab by going to SoftwareDaily.com and searching for the technologies or companies you are curious about . And if there is a subject that you want to hear covered, feel free to leave a comment on the episode, or send us a tweet @software_daily.

", + "Episodes Title": "Anyscale with Ion Stoica", + "Episodes Uid": "SED3432349777", + "Episodes Audio File": "c1575c0de130cb296606deec50d4d001.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "27ce6a98-ecb0-11ea-b5ca-039e13d8d742", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-02", + "Episodes Summary": "


", + "Episodes Title": "API Change Management with Aidan Cunniffe", + "Episodes Uid": "SED5241632642", + "Episodes Audio File": "74bd42300b5d9ed5c4c4a013f04e9499.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6g1", + "Episodes ID": "eb86b3dc-e328-11ea-91a2-97367549e1ce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_20_LynneTyeKeyValues.mp3", + "Episodes Pubdate Date": "2019-11-20", + "Episodes Summary": "

Key Values is a platform where companies are profiled with descriptions of their company values. These profiles describe features such as work-life balance, company culture, daily routines, and strategy.

Lynne Tye created Key Values with the goal of building a small business that would make money through connecting job seekers to companies with a culture that matched their own personal values system. Key Values has become highly successful, and Lynne is making enough money from the business to live comfortably.

In a previous episode, Lynne and I discussed her founding story and the engineering of Key Values. Today’s episode picks up a few years later, with Lynne having found significant success with her own company.

Lynne’s software business is an example of a growing trend: “Indie Hackers”. This trend was identified by Courtland Allen, founder of the Indie Hackers platform. Courtland is close friends with Lynne, and Lynne’s desire to start her own software company was influenced by her conversations with Courtland.

At a certain point, Lynne was considering raising money and growing Key Values. She was accepted into Y-Combinator. But she decided to stick with the Indie Hackers route, and grow the business independently. Lynne joins the show to talk about the process of starting a software business, and the pivotal decisions she has made around financing, growth, and her own psychology.

", + "Episodes Title": "Indie Hack or Venture Back with Lynne Tye", + "Episodes Uid": "SED9935000829", + "Episodes Audio File": "7d3da54626ebb82f2085943dd2973375.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 691, + "Episodes ID": "ec33dc1a-e328-11ea-91a2-87d08eb6cf98", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_30_MoatswithAstasiaMyers.mp3", + "Episodes Pubdate Date": "2019-09-30", + "Episodes Summary": "

Investors often use the term “moat” to describe the durable competitive advantage of a company.

When an investor puts money into a company, they are making that investment based on a valuation. That valuation is subjective–it is how much the investor thinks the company is worth. A valuation is determined by the present value of future cash flows. What are the future cash flows of a company? In order to figure that out, the investor needs to know how the business will look in the future.

This is why moats are so important. If an investor looks at how much money a business made this year, it does not tell the investor very much information about how much money the business will make in the future. If the business has a durable competitive advantage, then that means that the cash flows of the company are also durable. It also means that any compounding of those cash flows will be durable growth.

It is easy to understand durability for some businesses. Why do we keep using Google? Because there is no substitute search engine that is so integrated with our daily lives. Why do we keep using Facebook? Because there is no other social networking company that has all of our friends and family.

But what about companies with substitutes? There are lots of cloud providers, log management companies, and analytics providers. These are crowded markets, and yet in each of the crowded markets there seems to be a dominant player who captures the most market share. Why is that? How do software companies in competitive markets develop a moat?

Astasia Myers is a venture investor with Redpoint, a software investment firm that makes large bets on technology companies. Astasia joins the show to discuss how software companies form competitive advantages, as well as several specific markets such as log management and cloud cost optimization.

", + "Episodes Title": "Software Moats with Astasia Myers", + "Episodes Uid": "SED6415754809", + "Episodes Audio File": "8dceb08223cc3e88f5ac5d79901ea82c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1w7", + "Episodes ID": "1e46e4ae-e329-11ea-91a2-63e188a7c6fe", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Elixir_Edited_2.mp3", + "Episodes Pubdate Date": "2016-04-19", + "Episodes Summary": "

Elixir is a programming language built on top of the Erlang virtual machine. Elixir allows metaprogramming, polymorphism, and a web framework called Phoenix that has drawn positive comparisons to Ruby on Rails.

Jose Valim is today’s guest. He built Elixir to augment a language that he loved–Erlang. On Software Engineering Daily, we interviewed Joe Armstrong, the creator of Erlang, which was a very popular show–I encourage any listeners who are fans of Erlang to check it out. Erlang was built with concurrency in mind, and it has been rising in popularity as more of our applications are written to be distributed. In today’s episode we will discuss what Jose is building on top of Erlang.

", + "Episodes Title": "Elixir and Erlang with Jose Valim", + "Episodes Uid": "SED9390439848", + "Episodes Audio File": "e3060401a7c533e783982a46389d266d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1x7", + "Episodes ID": "1dd99cf0-e329-11ea-91a2-0b9e20ce8f94", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Docker_Edited.mp3", + "Episodes Pubdate Date": "2016-04-26", + "Episodes Summary": "

Docker is an open platform for distributed applications. Docker allows for standardized container runtimes and will be an important piece of infrastructure for many years to come. But if you are new to Docker, the technology can be confusing and intimidating.

What is a container? Why do I want to put my application in a container? Today’s guest Prakhar Srivastav wrote a long tutorial explaining the fundamentals of Docker. Prakhar explains why Docker is useful, how Docker works, and how you can get started.

", + "Episodes Title": "Docker for Beginners with Prakhar Srivastav", + "Episodes Uid": "SED3001493330", + "Episodes Audio File": "0ab064858776617d25af7adada8a9414.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1pi", + "Episodes ID": "21369ef2-e329-11ea-91a2-734e8c7a29c7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Hadoop_2_Edited.mp3", + "Episodes Pubdate Date": "2016-03-10", + "Episodes Summary": "

Hadoop was created in 2003. In the early years, Hadoop provided large scale data processing with MapReduce, and distributed fault-tolerant storage with the Hadoop Distributed File System. Over the last decade, Hadoop has evolved rapidly, with the support of a big open-source community.

Today’s guest is Mike Cafarella, co-creator of Hadoop. Mike takes us on a journey from past to present. Hadoop was based on the Google File System and MapReduce papers, and so Mike and I talk about what it was like to work on a distributed file system in 2004, and the challenges of implementing real software systems based on white papers. We also discuss YARN, and the wave of innovation that YARN enabled within the Hadoop ecosystem. Mike will also be presenting at Strata + Hadoop World in San Jose. We’re partnering with O’Reilly to support this conference – if you want to go to Strata, you can save 20% off a ticket with our code PCSED.

", + "Episodes Title": "Hadoop: Past, Present and Future with Mike Cafarella", + "Episodes Uid": "SED6754014519", + "Episodes Audio File": "635aa311022d5859763695b631b9a100.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6k9", + "Episodes ID": "eb141674-e328-11ea-91a2-b30a8ca95763", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_06_KubernetesProgressKelsey.mp3", + "Episodes Pubdate Date": "2020-01-06", + "Episodes Summary": "

When the Kubernetes project was started, Amazon Web Services was the dominant cloud provider. Most of the code that runs AWS is closed source, which prevents an open ecosystem from developing around AWS. Developers who deploy their application onto AWS are opting into a closed, controlled ecosystem, which has both costs and benefits.

The software industry has a history of closed and open ecosystems existing at the same time. AWS represented a huge closed ecosystem. With the amount of money at stake in the cloud business, it was only a matter of time before a more open ecosystem emerged.

Since the creation of Kubernetes, the world of cloud computing has evolved rapidly. Google and Microsoft have both invested heavily into Kubernetes, and Amazon itself has adapted to the newer competitive landscape with a Kubernetes offering of its own. Amazon has also made efforts to become more publicly involved in open source projects, including Kubernetes.

Kelsey Hightower has been a part of the Kubernetes ecosystem since the project was started. He is one of the most recognizable faces in the world of Kubernetes, delivering keynotes, appearing on podcasts, and co-authoring the popular Kubernetes Up and Running. Kelsey joins the show to discuss the progress in the Kubernetes ecosystem, and the competitive dynamics between Kubernetes and AWS.

", + "Episodes Title": "Kubernetes Progress with Kelsey Hightower", + "Episodes Uid": "SED4207629537", + "Episodes Audio File": "560bad390b6009ad1da5e692e2d7995e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "26a", + "Episodes ID": "14e30280-e329-11ea-91a2-cbaa64dd8c09", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Google_Cloud_Edited.mp3", + "Episodes Pubdate Date": "2016-09-16", + "Episodes Summary": "

Batch and stream processing systems have been evolving for the past decade. From MapReduce to Apache Storm to Dataflow, the best practices for large volume data processing have become more sophisticated as the industry and open source communities have iterated on them.

Dataflow and Apache Beam are projects that present a unified batch and stream processing system. A previous episode with Frances Perry discussed how they work in detail. In today’s episode, Eric Anderson discusses Cloud Dataflow, a service from Google that lets users manage their data processing pipelines without having to spin up individual servers to run them on.

Cloud Dataflow–like the “serverless” movement we have done several shows on–represents a growing shift towards cloud providers offering services that abstract away the operational challenges of managing compute nodes. If you have suggestions for topics in this area, please do send me an email.

", + "Episodes Title": "Cloud Dataflow with Eric Anderson", + "Episodes Uid": "SED9281987346", + "Episodes Audio File": "890ccc047af947940a3534e524ec5894.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6fs", + "Episodes ID": "eb902c6e-e328-11ea-91a2-1782105730b0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_18_CloudflareProducts.mp3", + "Episodes Pubdate Date": "2019-11-18", + "Episodes Summary": "

“Serverless” is an execution model where applications are scheduled and deployed to servers that are not directly managed by the application developer. 

In serverless execution, an application only loads and operates when a user actually needs to get a response from that application. This saves on resources, because many applications do not need to run at all times–they only need to be available for user requests.

The serverless model was popularized by Amazon Web Services Lambda. When Lambda first launched in 2015, it was an experimental product. Today, it is a widely used product and the market has validated the desire for serverless execution. Other cloud providers have introduced different models of serverless functionality including Google Cloud Functions, Azure Functions, and Fastly edge computing.

Zack Bloom is director of product for product strategy at Cloudflare, and he joins the show to discuss Cloudflare’s model for serverless execution. Zack also discusses Cloudflare’s growing product line, including the fast, privacy-protecting DNS resolver 1.1.1.1. Zack is a rare mix of engineering, business strategy, and product vision, which made for a great conversation.

For more content, you can check out our episodes about serverless technology and episodes about Cloudflare.

", + "Episodes Title": "Cloudflare Serverless with Zack Bloom", + "Episodes Uid": "SED7222118234", + "Episodes Audio File": "38307048e0db4ad5b9bfbed44ac3be24.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 741, + "Episodes ID": "e9b26cae-e328-11ea-91a2-e72665260295", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_20_ZoomVulnerability.mp3", + "Episodes Pubdate Date": "2020-04-20", + "Episodes Summary": "

Zoom video chat has become an indispensable part of our lives. In a crowded market of video conferencing apps, Zoom managed to build a product that performs better than the competition, scaling with high quality to hundreds of meeting participants, and millions of concurrent users.

Zoom’s rapid growth in user adoption came from its focus on user experience and video call quality. This focus on product quality came at some cost to security quality. As our entire digital world has moved onto Zoom, the engineering community has been scrutinizing Zoom more closely, and discovered several places where the security practices of Zoom are lacking.

Patrick Wardle is an engineer with a strong understanding of Apple products. He recently wrote about several vulnerabilities he discovered on Zoom, and joins the show to talk about the security of large client-side Mac applications as well as the specific vulnerabilities of Zoom.

", + "Episodes Title": "Zoom Vulnerabilities with Patrick Wardle", + "Episodes Uid": "SED1675099381", + "Episodes Audio File": "39aa36b1ebcb698dd3f3898babaf1cd1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6a5", + "Episodes ID": "ec1c590a-e328-11ea-91a2-3fe0c264f870", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_07_GDPRandDataPolicy.mp3", + "Episodes Pubdate Date": "2019-10-07", + "Episodes Summary": "

Data privacy policies have changed how software organizations need to operate.

As consumer preferences have shifted in favor of strong privacy, software companies are having to examine their policies around data collection and retention. Many software companies were started in a time with different norms around data. 

Building a new application that is compliant with GDPR is hard. Updating an existing application to align with GDPR is even harder.

Joshua Prismon is chief architect at FICO, a company that builds systems around credit scoring. Joshua joins the show to discuss how a large company like FICO has responded to changing consumer preferences through changes in its software architecture and engineering.

", + "Episodes Title": "GDPR in Practice with Joshua Prismon", + "Episodes Uid": "SED9181082053", + "Episodes Audio File": "124b997eb8905e4b12c6ca31374691cd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 689, + "Episodes ID": "ec418298-e328-11ea-91a2-c3ba78ea4dc7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_25_WebAssemblyattheEdge.mp3", + "Episodes Pubdate Date": "2019-09-25", + "Episodes Summary": "

Isolation is a fundamental concept in computer science. Software workloads are isolated from each other in order to keep resource access cleanly separated. 

When programs are properly isolated, it is easier for the programmer to reason about the memory safety of that program. When a program is not properly isolated, it can lead problems such as security flaws where one program can access the information that should be exclusive to a different program. Poor isolation can also lead to garbage collection problems, or running out of disk space.

Isolation takes many forms, including individual processes, containers, and virtual machines. The techniques for isolation evolve over time. A more recent technology that can assist with isolation is WebAssembly, a newer execution system that can run a variety of languages that compile down into the WebAssembly binary format. For previous episodes about WebAssembly, you can listen to some of the shows in our archives.

Tyler McMullen is the CTO at Fastly, a cloud provider that focuses on edge computing systems such as content delivery networking. Tyler has written and spoken about WebAssembly in detail. He joins the show to talk about computational isolation, and how WebAssembly presents new efficiencies for engineers looking to isolate their workloads. Full disclosure: Fastly, where Tyler works, is a sponsor of Software Engineering Daily.

", + "Episodes Title": "WebAssembly Isolation with Tyler McMullen", + "Episodes Uid": "SED5450239038", + "Episodes Audio File": "26e16f6aa84718a70b5d61211f36e910.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6i9", + "Episodes ID": "eb36bb70-e328-11ea-91a2-ff111ce8b81c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_12_BasicIncome_FloydMarinescu.mp3", + "Episodes Pubdate Date": "2019-12-12", + "Episodes Summary": "

Automation has the potential to eliminate rote jobs such as call center workers and truck drivers.

The downstream effects of automation also leads to new jobs, such as data labeling and robot operations. The net effect of modern automation technology is unclear, but it is likely to cause some disruption in the job market. Universal Basic Income (UBI) is an economic policy idea in which a government sends money to every person living in the country.

The goal of UBI is to reduce the impact of dramatic changes to the economy that are resulting from accelerating technological change. 

Floyd Marinescu is the CEO of C4 Media, the company that produces the QCon conference series and the InfoQ website for software engineers. Floyd has worked in the software industry for decades and in recent years has become an advocate for basic income. He is a friend and supporter of Andrew Yang, a 2020 presidential candidate who is running on a platform centered around a basic income policy. 

Floyd joins the show for a discussion of the future, and the potential positive and negative consequences of implementing a basic income.

", + "Episodes Title": "Basic Income with Floyd Marinescu", + "Episodes Uid": "SED8976950594", + "Episodes Audio File": "5b0081979bdbd86686640c3ac09ba0ce.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5h9", + "Episodes ID": "eed59616-e328-11ea-91a2-4bd222d4637a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_22_Superset.mp3", + "Episodes Pubdate Date": "2019-03-22", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Data engineering touches every area of an organization.

Engineers need a data platform to build search indexes and microservices. Data scientists need data pipelines to build machine learning models. Business analysts need flexible dashboards to understand the trends and customer use for a product.

Max Beauchemin is a data engineer who has worked at Airbnb, Lyft, and Facebook. He’s the creator of two successful open source projects: Apache Airflow and Apache Superset. In a previous show, Max discussed data engineering at Airbnb, and the usage of Airflow. In today’s show, Max discusses the engineering of Apache Superset.

Superset is an open source business intelligence web application. Superset allows users to create visualizations, slice and dice their data, and query it. Superset integrates with Druid, a database that supports exploratory, OLAP-style workloads.

One reason Superset is distinctive is that it is a full open source application. Many open source projects are tools like databases, command line tools, and web frameworks. Superset is an open source application that can be used by individuals who are not developers–so the audience is wider than the typical open source tool built for engineers.

Max joins the show to talk about his experience as a data engineer at Airbnb and Lyft, and the open source projects he has started.

", + "Episodes Title": "Apache Superset with Maxime Beauchemin", + "Episodes Uid": "SED6191352764", + "Episodes Audio File": "d80a22454a3186eaf92d93d01fb442f3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6px", + "Episodes ID": "eaae94c0-e328-11ea-91a2-9b5fe6228712", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_05_ChangelogHosts.mp3", + "Episodes Pubdate Date": "2020-02-05", + "Episodes Summary": "

The Changelog is a podcast about the world of open source. As open source has become closely tied with the entire software development lifecycle, The Changelog has expanded its coverage to the broader software industry.

Since starting the podcast ten years ago, Adam Stacoviak and Jerod Santo have become full-time podcasters, and they have started several other podcasts within the Changelog network, including Go Time, JS Party, and Practical AI. Throughout all of their shows, there is a consistent theme of technical, entertaining conversations about software.

In the last decade, so much has changed within open source: GitHub became the de facto social network for open source; Kubernetes created a widely used platform for distributed systems; React has given frontend developers a component system to consolidate around. Adam and Jerod return to the show to discuss their perspective on the past and future of open source, and their learnings from interviewing influential software professionals for 10 years.

", + "Episodes Title": "Changelog Podcasting with Adam Stacoviak and Jerod Santo", + "Episodes Uid": "SED3604315272", + "Episodes Audio File": "1f427d5d8e6b8d52ac0bf91ff5cb1d50.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "977a3614-fd4b-11ea-bbe7-e7151d4dfc2c", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-23", + "Episodes Summary": "


", + "Episodes Title": "Twitter Search with Nico Tonozzi", + "Episodes Uid": "SED6323280830", + "Episodes Audio File": "3d321add23755272170286265cbabdff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6zy", + "Episodes ID": "ea000b1c-e328-11ea-91a2-5f6ea6d66a9f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_26_RemoteTeamManagement.mp3", + "Episodes Pubdate Date": "2020-03-26", + "Episodes Summary": "

Remote engineering work makes some elements of software development harder, and some elements easier. With Slack and email, communication becomes more clear cut. Project management tools lay out the responsibilities and deliverables of each person. GitHub centralizes and defines the roles of developers.

On the other hand, remote work subtracts the role of nuanced conversation. There is no water cooler or break room. Work can become systematic, rigid, and completely transactional. Your co-workers are your allies, but they feel less like friends when you don’t see them every day. For some people, this can have a devastating long-term impact on their psyche.

Managers have the responsibility of ensuring the health and productivity of the people that work with them. Managing an all-remote team includes a different set of challenges than an in-person team. 

Ryan Chartrand is the CEO of X-Team, a team of developers who work across the world and collaborate with each other remotely. X-Team partners with large companies who need additional development work. Ryan joins the show to talk about the dynamics of leading a large remote workforce, as well as his own personal experiences working remotely.

", + "Episodes Title": "Remote Team Management with Ryan Chartrand", + "Episodes Uid": "SED9254062964", + "Episodes Audio File": "02a8d0f371f3c582549e49180b5b5a71.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "b4404410-ecb0-11ea-a4be-73c7edaab85a", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-04", + "Episodes Summary": "


", + "Episodes Title": "Robotic Process Automation with Antti Karjalainen", + "Episodes Uid": "SED8189708062", + "Episodes Audio File": "6ea7848dcf03079c3454bd60bf0acf2d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1a5", + "Episodes ID": "25d9e9a0-e329-11ea-91a2-9746efb7052a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Django_2.mp3", + "Episodes Pubdate Date": "2016-01-14", + "Episodes Summary": "

Django is an open source web development framework that was initially released in 2005, around the same time as Ruby on Rails. In many ways, the two frameworks are similar – they expedited web development by modularizing common components of web apps and enabling developers to quickly prototype and launch their products. They both encouraged the use of the MVC architectural pattern, with each respectively acting as the controller, allowing developers to use their own front end and database technologies.

But the path of the two frameworks diverged in other parameters, including mainstream adoption. Ruby on Rails became the sweetheart in Silicon Valley and elsewhere, while Django was loved by a core constituency of pythonistas who had used Python in other applications and fallen in love with it. At the peak of the frameworks’ popularity, there was a common question from new developers asking whether they should first learn Django or Rails – the answer often boiled down to whether you wanted to use Python or Ruby. In this episode, Frank discusses the history and growth of Django, and explains how it evolved in comparison with other frameworks.

Frank Wiles is the President of the Django Software Foundation, and partner at Revolution Systems. He worked at the Lawrence Journal-World newspaper, where Django was initially conceived and created.

", + "Episodes Title": "Django with Frank Wiles", + "Episodes Uid": "SED7990452467", + "Episodes Audio File": "96d3bb01ed19f11c7301aecee3c1aca4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "wr", + "Episodes ID": "2d94f068-e329-11ea-91a2-6784802602ef", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Racket_Edited.mp3", + "Episodes Pubdate Date": "2015-11-04", + "Episodes Summary": "

Racket is a functional programming language similar to Lisp and Scheme.

Matthew Flatt is a member of the Racket core development team and also a professor of computer science at the University of Utah.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Racket with Matthew Flatt", + "Episodes Uid": "SED7763916462", + "Episodes Audio File": "335b17b687c0546c0a8e101d70f72b2e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6nz", + "Episodes ID": "eac9ee3c-e328-11ea-91a2-4342afb57124", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_28_ReplicatedGrantMiller.mp3", + "Episodes Pubdate Date": "2020-01-28", + "Episodes Summary": "

Distributed systems are required to run most modern enterprise software. Application services need multiple instances for scalability and failover. Large databases are sharded onto multiple nodes. Logging services, streaming frameworks, and continuous integration tools all require the orchestration of more than one server.

Deploying a distributed system has historically been difficult because the nodes of the system must be managed by the underlying infrastructure. If I have a distributed database that I want to deploy, the complexity of that deployment is going to be different depending on whether I am running on AWS, or VMware, or my own bare metal server infrastructure. 

Heterogeneous server infrastructure makes it hard to sell distributed applications that get deployed to that infrastructure. A vendor that is selling a distributed database would need to figure out how to make their database work on the infrastructure of any given customer. 

Kubernetes has simplified the process of deploying a distributed application. Kubernetes is a container orchestration system that has steadily grown in popularity, to the point where the ecosystem is mature and the software is stable. Now that the software industry has a reliable, portable means of deploying a distributed application, the enterprise software market is becoming easier to enter for companies that sell a distributed application.

Replicated is a company that builds products for software delivery. Replicated allows for the distribution and updating of applications that would have been hard to deploy in the past. Grant Miller and Marc Campbell are the CEO and CTO of Replicated, and they join the show to talk about the modern enterprise software market, and the process of delivering software to companies that might otherwise have trouble consuming it. Full disclosure: Replicated is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Replicated Software Delivery with Grant Miller and Marc Campbell", + "Episodes Uid": "SED1206207818", + "Episodes Audio File": "322f565517ea1dfc8cdb7c7dc8912f2b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2en", + "Episodes ID": "0b4b8d78-e329-11ea-91a2-b30d4ff23a30", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ethicsofsoftware_edited.mp3", + "Episodes Pubdate Date": "2017-01-11", + "Episodes Summary": "

Software engineers are often one of the last lines of defense against potentially dangerous and unethical practices. Every software company encounters situations where the line between right and wrong is not clearly drawn.

Back in the year 2000 Bill Sourour was asked to code a project to help market a pharmaceutical product in a misleading way. Reflecting on this experience, Bill recently wrote about it on Medium, suggesting that developers should avoid doing things that compromise our ethics in small ways.

The more software defines our real world the more relevant the conversation around ethics becomes. In this episode, Bill and I explore the ethics of modern software development.

The Code I’m Still Ashamed Of

", + "Episodes Title": "Ethics of Software with Bill Sourour", + "Episodes Uid": "SED6501788038", + "Episodes Audio File": "c19ed264cfd5117845c6df7b8793b5ba.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "93cbbcae-fe04-11ea-a33d-8755c13a921d", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-25", + "Episodes Summary": "


", + "Episodes Title": "Developer Investing with Lee Edwards", + "Episodes Uid": "SED4331256155", + "Episodes Audio File": "cbb1f0462107aa092be09d8b475821b9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 722, + "Episodes ID": "e9da7bfe-e328-11ea-91a2-0bbd06e941a4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_07_kSQLDBKafka.mp3", + "Episodes Pubdate Date": "2020-04-07", + "Episodes Summary": "

Kafka is a distributed stream processing system that is commonly used for storing large volumes of append-only event data. Kafka has been open source for almost a decade, and as the project has matured, it has been used for new kinds of applications. 

Kafka’s pubsub interface for writing and reading topics is not ideal for all of these applications, which has led to the creation of ksqlDB, a database system built for streaming applications that uses Kafka as the underlying infrastructure for storing data.

Michael Drogalis is a principal product manager at Confluent, where he helped develop ksqlDB. Michael joins the show to discuss ksqlDB, including the architecture, the query semantics, and the applications which might want a database that focuses on streams. We have done many great shows on Kafka in the past, which you can find on SoftwareDaily.com. Also, if you are interested in writing about Kafka, we have a new writing feature that you can check out by going to SoftwareDaily.com/write.

", + "Episodes Title": "kSQLDB: Kafka Streaming Interface with Michael Drogalis", + "Episodes Uid": "SED5927273987", + "Episodes Audio File": "fb1fdd05fc7756f00ba4e2caac91e55f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "17s", + "Episodes ID": "26ac274e-e329-11ea-91a2-ab982838db58", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DS_Edited.mp3", + "Episodes Pubdate Date": "2016-01-04", + "Episodes Summary": "

Distributed computing is becoming an increasingly important and complex field within software engineering, with numbers of new data engineering and infrastructure frameworks being released each year. For a beginner, it can be tough to know where to start, so this episode may be considered a primer to learning about distributed systems independently.

Alvaro Videla is a core developer for RabbitMQ and a distributed systems blogger, and he joins Software Engineering Daily to explain some of the core concepts of distributed systems.

", + "Episodes Title": "Distributed Systems with Alvaro Videla", + "Episodes Uid": "SED2145917342", + "Episodes Audio File": "8791fd11a0942686606d9b99f3986fee.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "70q", + "Episodes ID": "e9e8d424-e328-11ea-91a2-fb1e95d4aac8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_02_ServerlessDevelopment.mp3", + "Episodes Pubdate Date": "2020-04-02", + "Episodes Summary": "

Serverless tools have come a long way since the release of AWS Lambda in 2014. Serverless apps were originally architected around Lambda, with the functions-as-a-service being used to glue together larger pieces of functionality and API services.

Today, many of the common AWS services such as API Gateway and DynamoDB have functionality built in to be able to respond to events. These services can use Amazon EventBridge to connect to each other. In many cases, a developer does not need AWS Lambda to glue services together in order to build an event-driven application.

Jeremy Daly is the host of the Serverless Chats podcast, a show about patterns and strategies in serverless architecture. Jeremy joins the show to talk about modern serverless development, and the new tools available in the AWS ecosystem.

", + "Episodes Title": "Serverless Development with Jeremy Daly", + "Episodes Uid": "SED2703117153", + "Episodes Audio File": "1e00da752f5393f5515677023d425337.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6tk", + "Episodes ID": "ea76403e-e328-11ea-91a2-5b06064013b0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_20_OpenSourceVentureEricAnderson.mp3", + "Episodes Pubdate Date": "2020-02-20", + "Episodes Summary": "

In a modern data platform, distributed streaming systems are used to read data coming off of an application in real-time. There are a wide variety of streaming systems, including Kafka Streams, Apache Samza, Apache Flink, Spark Streaming, and more. 

When Eric Anderson joined the show back in 2016, he was working at Google on Google Cloud Dataflow, a managed service for handling streaming data. Today, he works as an investor at Scale Venture Partners. In his current job, he analyzes companies built around data infrastructure, developer tooling, and other enterprise engineering domains.

Eric also hosts the podcast Contributor, which explores open source maintainers and the stories of their projects. His podcast has featured the creators of projects such as Envoy, Alluxio, and Chef. In today’s episode, Eric returns to the show to discuss data infrastructure, investing, and the evolving world of open source.

", + "Episodes Title": "Data Infrastructure Investing with Eric Anderson", + "Episodes Uid": "SED4316385999", + "Episodes Audio File": "dfd307dfc17461d346aa0f3f55eebff8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2dc", + "Episodes ID": "0dae1cac-e329-11ea-91a2-6b925ccc0d2d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/sampling_edited.mp3", + "Episodes Pubdate Date": "2016-12-22", + "Episodes Summary": "

Every song you hear on the radio is written with a computer. Computer musicians mostly use synthesizers and samples to compose these songs. A sample is a snippet of recorded sound, sometimes taken from a songs, a movie, or another source. The more samples a musician has access to the better.

SampleFocus is a platform where musicians upload and download samples to build songs with. Daniel Trostli is the engineer who is building SampleFocus, and he joins the show to discuss how people use samples to write music and how he built SampleFocus.

I met Daniel at the Launch Scale event, a conference about building businesses, and when I was having lunch with Daniel, he told me about working on this personal project full-time, and some of the different business models he was exploring. It’s a great episode for anyone who is thinking about turning a side project into a business.

", + "Episodes Title": "Sampling with Daniel Trostli", + "Episodes Uid": "SED5490631907", + "Episodes Audio File": "fadc7fe4dba95cd57f362a8df0a91a0a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6xq", + "Episodes ID": "ea292be6-e328-11ea-91a2-471e21977705", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_13_Descript.mp3", + "Episodes Pubdate Date": "2020-03-13", + "Episodes Summary": "

Descript is a software product for editing podcasts and video.

Descript is a deceptively powerful tool, and its software architecture includes novel usage of transcription APIs, text-to-speech, speech-to-text, and other domain-specific machine learning applications. Some of the most popular podcasts and YouTube channels use Descript as their editing tool because it provides a set of features that are not found in other editing tools such as Adobe Premiere or a digital audio workstation.

Descript is an example of the downstream impact of machine learning tools becoming more accessible. Even though the company only has a small team of machine learning engineers, these engineers are extremely productive due to the combination of APIs, cloud computing, and frameworks like TensorFlow.

Descript was founded by Andrew Mason, who also founded Groupon and Detour, and Andrew joins the show to describe the technology behind Descript and the story of how it was built. It is a remarkable story of creative entrepreneurship, with numerous takeaways for both engineers and business founders.

", + "Episodes Title": "Descript with Andrew Mason", + "Episodes Uid": "SED4796471571", + "Episodes Audio File": "3f93f3e7b8703e70f10eea1b9c67b861.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24y", + "Episodes ID": "16b8054c-e329-11ea-91a2-e7a690a29ee9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/TensorFlow_with_Rajat__Edited.mp3", + "Episodes Pubdate Date": "2016-08-18", + "Episodes Summary": "

TensorFlow is Google’s open source machine learning library. Rajat Monga is the engineering director for TensorFlow. In this episode, we cover how to use TensorFlow, including an example of how to build a machine learning model to identify whether a picture contains a cat or not.
\nTensorFlow was built with the mission of simplifying the process of deploying a machine learning model from research to production, so we also talk about that, as well as how TensorFlow can be used effectively in combination with Google’s open-source cluster manager, Kubernetes.

", + "Episodes Title": "TensorFlow in Practice with Rajat Monga", + "Episodes Uid": "SED7499219540", + "Episodes Audio File": "bf335cc6893a0ba941b86b4b172a62b9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1zr", + "Episodes ID": "1c06842e-e329-11ea-91a2-63f6e5bd7e51", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Purify_Edited.mp3", + "Episodes Pubdate Date": "2016-05-31", + "Episodes Summary": "

Coding boot camps are a subject of controversy. Critics of boot camps defend the conventional university system, and argue that boot camp graduates do not have enough experience to write quality software. But the reality is that some boot camp graduates have found success from this new educational path.

After graduating high school, Kenny Tran attended one coding boot camp, then spent some time living at home absorbed in his personal projects. Eventually, he went to second coding boot camp–his form of graduate school. During his second boot camp, Kenny worked on PurifyCSS, a module that can reduce the size of front-end projects by 60%. Today, Kenny works at the groundbreaking company Mesosphere–completing a career arc that proves coding boot camps are enough of an education to rival traditional university learning.

", + "Episodes Title": "Boot Camps, Mesosphere, and Open-Source with Kenny Tran", + "Episodes Uid": "SED2995158279", + "Episodes Audio File": "f2c2d58ce4377e78bae8a4e6829cd9fa.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7af", + "Episodes ID": "e9066d14-e328-11ea-91a2-bb35221de4c7", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_05_UberDataVisualization.mp3", + "Episodes Pubdate Date": "2020-06-05", + "Episodes Summary": "

Uber needs to visualize data on a range of different surfaces. A smartphone user sees cars moving around on a map as they wait for their ride to arrive. Data scientists and operations researchers within Uber study the renderings of traffic moving throughout a city.

Data visualization is core to Uber, and the company has developed a stack of technologies around visualization in order to build appealing, highly functional applications. DeckGL is a library for high-performance visualizations of large data sets. LumaGL is a set of components that targets high performance rendering. These and other tools make up VisGL, the data visualization technology that powers Uber.

Uber’s visualization team included Ib Green, who left Uber to co-found Unfolded.ai, a company that builds geospatial analytics products. He joins the show to discuss his work on visualization products and libraries at Uber, as well as the process of taking that work to found Unfolded.ai. Full disclosure: I am an investor in Unfolded.ai.

", + "Episodes Title": "Uber’s Data Visualization Tools with Ib Green", + "Episodes Uid": "SED9306287630", + "Episodes Audio File": "93d4c505569eb287c3ed6bd926588aea.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2a8", + "Episodes ID": "111e9e66-e329-11ea-91a2-139087de47c2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/awsguide_edited_2.mp3", + "Episodes Pubdate Date": "2016-11-14", + "Episodes Summary": "

Amazon Web Services changed the economics of building an internet application. Instead of having to invest tens of thousands of dollars up front for hardware, developers can pay for services over time as their application scales.

As AWS has grown to be a gigantic platform, the documentation about how to use cloud infrastructure has become insufficient. As an answer to this, Joshua Levy initiated The Open Guide to Amazon Web Services, an open-source collection of resources available on github. Joshua has experience at a variety of companies, including Viv, the conversational interface that was recently acquired by Samsung.

In our conversation, Josh brought his years of experience to the table to explain the risks, benefits, and alternatives of Amazon Web Services. Josh has become a friend over the last year, and if you get the chance to have a conversation with him, I highly recommend it. He will be at the re:Invent conference in Vegas at the end of this month (November) and if you are interested in talking to him about the AWS Open Guide, or anything else, reach out to him.

", + "Episodes Title": "AWS Open Guide with Joshua Levy", + "Episodes Uid": "SED1250456610", + "Episodes Audio File": "a1feb313dadee6833e419baee8ad9950.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6o2", + "Episodes ID": "eac576c2-e328-11ea-91a2-27de107b2168", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_29_PantherSecurity.mp3", + "Episodes Pubdate Date": "2020-01-29", + "Episodes Summary": "

Large software companies have lots of users, and the activity from those users results in high volumes of traffic. These companies also have a large surface area across the enterprise. 

There are hundreds of services and databases that are fulfilling user requests. As these requests enter the infrastructure of the enterprise, the requests travel through the different services and result in database queries, payments, and other transactions. These transactions result in the generation of log messages. The log messages tell the story of what is happening across the entire company. 

Log messages can provide valuable data for security and site reliability engineering. But analyzing a high volume of log data requires a scalable system that can account for that high volume. 

Jack Naglieri is the CEO of Panther Security. He previously worked at Airbnb, where he helped develop a system called StreamAlert. At Airbnb, log messages are buffered into distributed queueing systems like Kafka or Kinesis, and they are written to bucket storage systems like S3. Those logs are processed by AWS Lambda functions that test the log messages for rules defined by a system operator.

Jack left Airbnb and started Panther Security to generalize the tools he built within Airbnb and build a company around the same ideas. Jack joins the show to discuss modern logging infrastructure, his work at Airbnb, and his experience building Panther.

", + "Episodes Title": "Cloud Log Analysis with Jack Naglieri", + "Episodes Uid": "SED2255625749", + "Episodes Audio File": "9d605041f0996b91c5578e121ab1c11a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "xs", + "Episodes ID": "2d006b0a-e329-11ea-91a2-efe15a9a6226", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/wolfram_Edited_2.mp3", + "Episodes Pubdate Date": "2015-11-10", + "Episodes Summary": "

Wolfram Research makes computing software powered by the Wolfram language, a knowledge-based programming language that draws from symbolic and functional programming paradigms.

Stephen Wolfram is the Founder and CEO of Wolfram Research, and also the author of A New Kind of Science.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Knowledge-Based Programming with Stephen Wolfram", + "Episodes Uid": "SED7788126687", + "Episodes Audio File": "c2c8100a691d4dd7c91da694b8ac8bbf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ct", + "Episodes ID": "e8d229d2-e328-11ea-91a2-8bfa4c382a9a", + "Episodes Original URL": "https://sd-profile-pictures.s3-us-west-2.amazonaws.com/adfree/2019_12_20_FreeCodeCampQuincy_adfree.mp3", + "Episodes Pubdate Date": "2020-06-22", + "Episodes Summary": "

Originally published December 20, 2019. We are taking a few weeks off. We’ll be back soon with new episodes.

freeCodeCamp was started five years ago with the goal of providing free coding education to anyone on the Internet.

freeCodeCamp has become the best place to begin learning how to write software. There are many other places that a software engineer should visit on their educational journey, but freeCodeCamp is the best place to start, because it is free, and there are no advertisements. 

For most people learning to code, the price of that education is important, because they are learning to code to build a new career. It’s also important that a new programmer learns from an unbiased source of information, because an ad-supported environment will educate the new programmer towards products that they might not need.

freeCodeCamp has not been easy to build. Building freeCodeCamp has required expertise in software engineering, business, media, and community development. The donation-based business model of freeCodeCamp doesn’t collect very much money. Why would somebody build a non-profit when they could spend their time building a highly profitable software company?

Quincy Larson is the founder of freeCodeCamp, and he joins the show for a special episode about his backstory and the journey to building the best place on the Internet for a new programmer to begin.

", + "Episodes Title": "freeCodeCamp with Quincy Larson (Summer Break Repeat)", + "Episodes Uid": "SED4705116868", + "Episodes Audio File": "b4ff55a4231f76cc2adf1e864f173de2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ba", + "Episodes ID": "0f8d662c-e329-11ea-91a2-5796eaf6b199", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/robotlawyer_edited_1.mp3", + "Episodes Pubdate Date": "2016-12-02", + "Episodes Summary": "

You have probably received a parking ticket that you felt was unfair,   but instead of fighting it, you paid the expensive price to get rid of it quickly. Fighting a parking ticket sounds like it would be so time consuming that it is a better decision to just pay for it. When Joshua Browder was faced with this situation, his response was different. He decided there should be an automated solution to fighting parking tickets, and he made the user interface a chat bot.

It’s not obvious why a chat bot interface for fighting parking tickets makes sense, but in my discussion with Joshua, he explained that a chat bot interface is actually useful for a wide variety of legal services. The way that a lawyer interacts with a client is often so mechanistic as to be similar to a robot.

This episode was a fascinating episode that serves as a great follow-up to the recent shows on chat bots–ChatOps, Bot Day, and Slack Bots. Thanks again to O’Reilly for giving me a ticket to Bot Day last month, as it really got me thinking about chat bots as an important user interface.

", + "Episodes Title": "Robot Lawyer with Joshua Browder", + "Episodes Uid": "SED9629298409", + "Episodes Audio File": "7d820668209c53af092c5812fe6d3122.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1qe", + "Episodes ID": "2085c672-e329-11ea-91a2-b36c17c7ba36", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Discourse_Edited.mp3", + "Episodes Pubdate Date": "2016-03-15", + "Episodes Summary": "

Stack Overflow is used by developers to find out how to build software. Stack Overflow is both a tool and a community, and today’s guest Jeff Atwood has made a career out of building tools and communities. As the co-founder of Stack Exchange and Discourse.org, Jeff has been solving the problem of civilized online communication for seven years.

In today’s episode of Software Engineering Daily, Jeff Atwood talks about building online communities from the perspective of an engineer as well as a sociologist.

", + "Episodes Title": "State of Programming with Jeff Atwood", + "Episodes Uid": "SED7159971664", + "Episodes Audio File": "9fe09e0723512293ee646ea25a327aff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ak", + "Episodes ID": "e8eff610-e328-11ea-91a2-1b72ba7e1fef", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_12_CruiseSimulation.mp3", + "Episodes Pubdate Date": "2020-06-12", + "Episodes Summary": "

Cruise is an autonomous car company with a development cycle that is highly dependent on testing its cars–both in the wild and in simulation. The testing cycle typically requires cars to drive around gathering data, and that data to subsequently be integrated into a simulated system called Matrix.

With COVID-19, the ability to run tests in the wild has been severely dampened. Cruise cannot put so many cars on the road, and thus has had to shift much of its testing procedures to rely more heavily on the simulations. Therefore, the simulated environments must be made very accurate, including the autonomous agents such as pedestrians and cars.

Tom Boyd is VP of Simulation at Cruise. He joins the show to talk about the testing workflow at Cruise, how the company builds simulation-based infrastructure, and his work managing simulation at the company.

", + "Episodes Title": "Cruise Simulation with Tom Boyd", + "Episodes Uid": "SED8002975877", + "Episodes Audio File": "5f5160cbd9939a3c67e94fa8f7170e87.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1dm", + "Episodes ID": "2421245c-e329-11ea-91a2-632e208e715e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Benchmarking_Edited.mp3", + "Episodes Pubdate Date": "2016-02-03", + "Episodes Summary": "

Stream processing engines are often the component of data engineering stacks with the most variety, with the big data ecosystem offering several compelling options. Assessing the differences between projects like Flink, Storm, and Spark Streaming is difficult without an agreed upon set of metrics to compare them on. Fortunately, the Yahoo engineering team created a set of benchmarks to do exactly this. On today’s episode, Jeff and Bobby compare streaming frameworks through the performance on several of Yahoo’s benchmarking tests.

Bobby Evans is an architect at Yahoo working on streaming frameworks, primarily on Apache Storm. He is also the Apache Storm Incubating PMC at The Apache Software Foundation.

", + "Episodes Title": "Benchmarking Stream Processing Frameworks with Bobby Evans", + "Episodes Uid": "SED6922736589", + "Episodes Audio File": "50989794cb2c0f78effd89895fa33552.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1pc", + "Episodes ID": "214a0d16-e329-11ea-91a2-6ba72b003d9e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Airbnb_Edited.mp3", + "Episodes Pubdate Date": "2016-03-09", + "Episodes Summary": "

When a company gets big enough, there is so much data to be processed that an entire data engineering team becomes responsible for managing this data and making it available to other teams. Airbnb is one such company.

Max Beauchemin works on the data engineering team at Airbnb, where he creates infrastructure and tooling for managing data. In this episode of Software Engineering Daily, we talk about AIrflow, a workflow scheduler that assists in job processing. If you don’t know what a workflow is, or a job, we will explain that in this episode. Max and I also talk about Panoramix, a data slicing and visualization tool that helps data scientists and business analysts understand large volumes of data. Max will also be presenting at Strata + Hadoop World in San Jose. We’re partnering with O’Reilly to support this conference – if you want to go to Strata, you can save 20% off a ticket with our code PCSED.

", + "Episodes Title": "Data Engineering at Airbnb with Maxime Beauchemin", + "Episodes Uid": "SED3722254060", + "Episodes Audio File": "137acf138bc4f5477b1ef3a2a0d2a25f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ze", + "Episodes ID": "ed057afe-e328-11ea-91a2-3beffacaa63f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_26_IPOswithTomasTunguz.mp3", + "Episodes Pubdate Date": "2019-07-26", + "Episodes Summary": "

Software companies such as Slack, Zoom, and Uber have recently gone public.

When a company goes public, they issue a document called an S-1. Within the S-1, there is a wealth of information about the company, providing a detailed story about the company’s business model, economics, and future prospects. The S-1 describes the operating model and the philosophy of a newly public company.

Going public serves several purposes. Being public allows a company to gain access to the public capital markets. It allows previous investors to have a liquidity event, by selling the shares that they purchased from the company in private markets. Being public also puts some constraints and visibility on a company, which can be useful for a company that is trying to develop internal discipline.

In the software industry, it is useful for most people to understand the dynamics of going public. A technology worker who is earning equity at a private company needs to understand the roadmap to their company going public, or potentially getting acquired. Anyone who invests in public technology stocks is evaluating the different available options for investment, and considering the best software companies to place a bet on.

Tom Tunguz is a venture investor at Redpoint, and the author of a popular blog at tomasztonguz.com. In a recent series of posts, Tom has evaluated the S-1s and compared the growth dynamics between a variety of newer public software companies. Tom joins today’s show to discuss his writing, and offer reflections on what can be learned about company building from the recent series of IPOs and direct listings.

", + "Episodes Title": "Software IPOs with Tomas Tunguz", + "Episodes Uid": "SED6177100052", + "Episodes Audio File": "956643351ffb9db6d7d7ced4ee9ff0c6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6aa", + "Episodes ID": "ec057c6c-e328-11ea-91a2-8f429eeb7ad1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_14_Render2.mp3", + "Episodes Pubdate Date": "2019-10-14", + "Episodes Summary": "

Render is a cloud provider built on top of Amazon Web Services and Google Cloud. Render uses the compute abstractions provided by the major cloud providers to build a second layer cloud provider with the goal of providing a better user experience.

Anurag Goel is the founder of Render, and he returns to the show to discuss how Render works, and why there is a need for a new cloud provider. 

Everyone knows that the market for cloud providers is gigantic, so why are so few companies pursuing it? From Anurag’s perspective, there is no good reason. AWS, Google, Azure, Digital Ocean, and Heroku have only explored a small percentage of the potential ways a cloud provider could be built.

Anurag shares his strategy for building Render, and also talks through his belief around modern software engineering, including his belief that developers mostly choose their tools based on what they read from popular websites rather than what solves their problems–a phenomenon which he describes as “fashion driven development.”

", + "Episodes Title": "How To Build A Cloud Provider with Anurag Goel", + "Episodes Uid": "SED6915757662", + "Episodes Audio File": "4e4f2a66c8b730a1d9bf8ffd3bda56b2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5i1", + "Episodes ID": "eec81798-e328-11ea-91a2-ab02222220ec", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_27_LoggingwithRenaudBoutet.mp3", + "Episodes Pubdate Date": "2019-03-27", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Log management requires the processing and indexing of high volumes of semi-structured data. A log management service takes log data and puts it in a cloud-hosted application so that application operators can access those logs to troubleshoot issues.

A large tech company will produce terabytes of logs. Those logs are produced on the host where a service is running. A logging agent on that host will transfer the logs to the log management service in the cloud. Once the logs are in the cloud, they are parsed, indexed, and stored in a way that is easy to query.

In 2014, Renaud Boutet co-founded Logmatic, a log management service that eventually became a leading provider. Logmatic was acquired by Datadog, and Renaud now works as a vice president at Datadog. In today’s episode, Renaud joins the show to talk about the architecture of a log management service. We talk about storage tiers, scalability requirements, failover strategies, and logging for serverless functions.

Full disclosure: Datadog is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Scaling Log Management with Renaud Boutet", + "Episodes Uid": "SED3184632915", + "Episodes Audio File": "95485c45bf637521d688899fe07d0d86.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2do", + "Episodes ID": "0cbc4a58-e329-11ea-91a2-4b867ce7ed18", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/mikewolfe_edited.mp3", + "Episodes Pubdate Date": "2016-12-29", + "Episodes Summary": "

In the 1990s, the barriers to starting a company were significant. Not only did you need an idea, you needed $200,000 for servers and Oracle licenses. With cloud computing, the up-front financial costs of getting a company off the ground have been mostly eliminated–but the idea of starting a company is still perceived as risky.

The process of building software has changed dramatically in the last twenty years, but many of the challenges of managing a software company remain timeless. How do you hire properly? How do you keep track of a software stack that is growing in complexity? How do you handle dissenting opinions from employees?

Mike Wolfe has been building software companies since the 1990s and joins the show to discuss how to build products and manage engineering teams. It’s a wide-ranging discussion including technological trends, interpersonal skills, and startup financing.

", + "Episodes Title": "Startup Engineering with Mike Wolfe", + "Episodes Uid": "SED4749048361", + "Episodes Audio File": "f090e5c1849844f1391fb47a883ae136.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 742, + "Episodes ID": "e9adef1c-e328-11ea-91a2-7f057fb1c834", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_21_FrontendMonitoring.mp3", + "Episodes Pubdate Date": "2020-04-21", + "Episodes Summary": "

Web development has historically had more work being done on the server than on the client. The observability tooling has reflected this emphasis on the backend. Monitoring tools for log management and backend metrics have existed for decades, helping developers debug their server infrastructure.

Today, web frontends have more work to do. Detailed components in frameworks such as React and Angular might respond quickly without waiting for a network request, with their mutations being processed entirely in the browser. This results in better user experiences, but more work is being done on the client side, away from the backend observability tools.

Matt Arbesfeld is a co-founder of LogRocket, a tool that records and plays back browser sessions and allows engineers to look at those sessions to understand what kinds of issues are occurring in the user’s browser. Matt joins the show to talk about the field of frontend monitoring, and the engineering behind his company LogRocket.

", + "Episodes Title": "Frontend Monitoring with Matt Arbesfeld", + "Episodes Uid": "SED1978113814", + "Episodes Audio File": "afb80e281f3ad756be1d4c333cc2a090.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ge", + "Episodes ID": "e8730c4a-e328-11ea-91a2-9f4f3b4ade02", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_20_Cortex.mp3", + "Episodes Pubdate Date": "2020-07-20", + "Episodes Summary": "

Managing microservices becomes a challenge as the number of services within the organization grows. With that many services comes more interdependencies–downstream and upstream services that may be impacted by an update to your service. 

One solution to this problem: a dashboard and newsfeed system that lets you see into the health and changes across your services. With this kind of system, you can avoid accidentally shipping code that will impact other service owners. It can also help with testing, giving you an end-to-end picture for how a test can impact other services.

Anish Dhar and Ganesh Datta are co-founders of Cortex, a system for managing your services. Anish and Ganesh join the show to talk about their work building Cortex, and the value that it provides to the companies that use it.

In a previous show we covered a company called Effx, which does something similar.

", + "Episodes Title": "Cortex: Microservices Management with Anish Dhar and Ganesh Datta", + "Episodes Uid": "SED3523862895", + "Episodes Audio File": "86c241a53ea6527ca741b68aaaa2eef4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5zd", + "Episodes ID": "ed09f4f8-e328-11ea-91a2-2f30175a37bc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_25_EnvoyMobilewithMattKlein.mp3", + "Episodes Pubdate Date": "2019-07-25", + "Episodes Summary": "

Envoy is an open source edge and service proxy that was originally developed at Lyft. 

Envoy is often deployed as a sidecar application that runs alongside a service and helps that service by providing features such as routing, rate limiting, telemetry, and security policy. Envoy has gained significant traction in the open source community, and has formed the backbone of popular service mesh projects such as Istio.

Envoy has been mostly used as a backend technology, but the potential applications of Envoy include frontend client applications as well. The goal of Envoy is to make the network easier to work with–and the network includes client applications such as mobile apps running on a phone.

Envoy Mobile is a network proxy for mobile applications. Envoy Mobile brings many of the benefits of Envoy to the mobile client ecosystem. It provides mobile developers with a library that can simplify or abstract away many of the modern advances that have been made in networking in recent years, such as HTTP2, gRPC, and QUIC.

Matt Klein is the creator of Envoy, and he joins the show to discuss Envoy Mobile. Matt describes how the networking challenges of mobile applications are similar to those of backend systems and cloud infrastructure. We discuss the advances in networking technology that Envoy Mobile helps bring to the mobile ecosystem, and also touch on the scalability challenges that Matt is seeing at Lyft.

", + "Episodes Title": "Envoy Mobile with Matt Klein", + "Episodes Uid": "SED9290592404", + "Episodes Audio File": "d8b735cb92c343c4c62e867db4fa855c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 688, + "Episodes ID": "ec46325c-e328-11ea-91a2-6f28c65d9377", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_24_CloudFoundrywithAbbyKearns.mp3", + "Episodes Pubdate Date": "2019-09-24", + "Episodes Summary": "

Cloud Foundry is a system for managing distributed applications.

Cloud Foundry was released in 2011, and has been widely adopted by enterprises that need a platform for deploying and scaling the applications that run within their company. The ecosystem around Cloud Foundry includes systems for continuous delivery, pubsub messaging, and containerization.

Abby Kearns is the executive director at Cloud Foundry Foundation, a nonprofit with the goal of raising awareness and adoption of the Cloud Foundry open source project. Abby joins the show to discuss her work with Cloud Foundry, and how the ecosystem has evolved with the maturity of distributed computing. We also talk about what enterprises need from an application runtime platform and how Cloud Foundry has adopted Kubernetes.

", + "Episodes Title": "Cloud Foundry with Abby Kearns", + "Episodes Uid": "SED7536785194", + "Episodes Audio File": "cfac8f98459108ca954dbae0a6be0beb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7is", + "Episodes ID": "e83eb45e-e328-11ea-91a2-874f9bc84db1", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_18_Metabase.mp3", + "Episodes Pubdate Date": "2020-08-18", + "Episodes Summary": "

Business intelligence tooling allows analysts to see large quantities of data presented to them in a flexible interface including charts, graphs, and other visualizations. BI tools have been around for decades, and as the world moves towards increased open source software, the business intelligence tools are following that trend.

Metabase is an open source business intelligence system that has been widely adopted by enterprises. It includes all the common tools that are expected from a business intelligence system: large-scale data ingestion, visualization software, and a flexible user interface.

Sameer Al-Sakran is the CEO of Metabase and he joins the show to talk about Metabase’s design, engineering, and usage.

", + "Episodes Title": "Metabase: Business Intelligence Open Source with Sameer Al-Sakran", + "Episodes Uid": "SED4921963185", + "Episodes Audio File": "8f334c4bc11d80abe2659a88468c2963.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6bm", + "Episodes ID": "ebed6bb8-e328-11ea-91a2-b77eb0ab16de", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_21_DarkLang.mp3", + "Episodes Pubdate Date": "2019-10-21", + "Episodes Summary": "

Dark Lang is a programming language that is tightly integrated with the cloud. 

Dark takes an opinionated approach that most developers are going to want to run their applications in the cloud, and this perspective influences how Dark looks at deployments, IDEs, exception handling, and other aspects of software development.

Paul Biggar is the founder of CircleCI, and ran the company for eight years before leaving to found Dark with Ellen Chisa. Ellen is a software engineer and the CEO of Dark. Paul and Ellen join the show to give their perspective on modern software engineering, and why it was time to build a new high level language that assumes the presence of a cloud.

It is difficult to get programmers to adopt a new language. It is even harder to get those programmers to pay for products built around that language. But the timing could be perfect for Dark. 

Software development is undergoing tremendous change–and many of these changes work to Dark’s advantage, such as the growing adoption of feature flags, low code tools, and sophisticated continuous delivery workflows. Whether or not Dark is a success, it is a bold project, and the team is working on something they believe in.

We also discussed AWS–and whether the largest cloud provider has an obligation to contribute back to the open source community.

", + "Episodes Title": "Dark Lang with Ellen Chisa and Paul Biggar", + "Episodes Uid": "SED5656352801", + "Episodes Audio File": "0aba368cb0754bd323950591eee1330f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ch", + "Episodes ID": "245635b6-e329-11ea-91a2-7343f2cfbc1d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Keras_Edited.mp3", + "Episodes Pubdate Date": "2016-01-29", + "Episodes Summary": "

Keras is a minimalist, highly modular neural networks library, written in Python and capable of running on top of either TensorFlow or Theano. It was developed with a focus on enabling fast experimentation. In this episode, François discusses the state of deep learning, and explains why the field is experiencing a cambrian explosion that eventually may taper off. He explains the need for Keras and why its simplicity and ease makes it a useful deep learning library for developers to experiment and build with.

François Chollet is the author of Keras and the founder of Wysp, learning platform for artists. He currently works for Google as a deep learning engineer and researcher.

", + "Episodes Title": "Deep Learning and Keras with François Chollet", + "Episodes Uid": "SED1370427735", + "Episodes Audio File": "ba47e92ee69144f2481252c8eaa41eeb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 757, + "Episodes ID": "e98f1a4c-e328-11ea-91a2-07a06a926617", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_29_Prefect.mp3", + "Episodes Pubdate Date": "2020-04-29", + "Episodes Summary": "

A data workflow scheduler is a tool used for connecting multiple systems together in order to build pipelines for processing data. A data pipeline might include a Hadoop task for ETL, a Spark task for stream processing, and a TensorFlow task to train a machine learning model. 

The workflow scheduler manages the tasks in that data pipeline and the logical flow between them. Airflow is a popular data workflow scheduler that was originally created at Airbnb. Since then, the project has been adopted by numerous companies that need workflow orchestration for their data pipelines. Jeremiah Lowin was a core committer to Airflow for several years before he identified several features of Airflow that he wanted to change.

Prefect is a dataflow scheduler that was born out of Jeremiah’s experience working with Airflow. Prefect’s features include data sharing between tasks, task parameterization, and a different API than Airflow. Jeremiah joins the show to discuss Prefect, and how his experience with Airflow led to his current work in dataflow scheduling.

", + "Episodes Title": "Prefect Dataflow Scheduler with Jeremiah Lowin", + "Episodes Uid": "SED4158301542", + "Episodes Audio File": "4b8bdc13eb0ebf16bf775da8ff5e6504.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23r", + "Episodes ID": "19003720-e329-11ea-91a2-573c15ad41d7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Kubernetes_Origins_Edited.mp3", + "Episodes Pubdate Date": "2016-07-21", + "Episodes Summary": "

The container management system Kubernetes was open sourced by Google with the intention of creating a cloud service based on the project. Today, the Kubernetes ecosystem is looking similar to the Android ecosystem, with different vendors providing different ways to use Kubernetes, from RedHat’s OpenShift to Google Container Engine.

Craig Mcluckie was a member of the team who originally devised Kubernetes, and he joins the show to talk about the origins of Kubernetes and where the project is headed, exploring both the technical architecture and Google’s business strategy around Kubernetes.

", + "Episodes Title": "Kubernetes Origins with Craig Mcluckie", + "Episodes Uid": "SED6232017412", + "Episodes Audio File": "da527528e835227291fff37ed0e0f8b5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "26n", + "Episodes ID": "147cb494-e329-11ea-91a2-bf44a61fde5f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Devoxx4Kids_edited.mp3", + "Episodes Pubdate Date": "2016-09-21", + "Episodes Summary": "

Devoxx4Kids is an organization that is inspiring children through robotics, programming, and engineering. Kids who attend a Devoxx4Kids workshop are exposed to entertaining and educational activities, such as writing a Minecraft mod or programming an Arduino.

Arun Gupta is a software engineer and the president of the board for Devoxx4Kids USA. In this episode we discuss coding education for kids, and what happens at a Devoxx4Kids workshop. If you have a kid who you want to expose to technology, this episode has some great suggestions for how to do that.

", + "Episodes Title": "Devoxx4Kids with Arun Gupta", + "Episodes Uid": "SED6477926505", + "Episodes Audio File": "cf20b351f1fedf46da12299bf0f74907.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "26m", + "Episodes ID": "145ec5f6-e329-11ea-91a2-ff0a3a375165", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Techleadership_Edited.mp3", + "Episodes Pubdate Date": "2016-09-22", + "Episodes Summary": "

The role of “tech lead” is a combination of a software engineer, a project manager, and an architect. A tech lead might spend 30% of her time coding and 70% managing a project, resolving conflicts, and planning.

In today’s episode, we discuss the structure of software teams, and when it might make sense to have a tech lead on your team, in contrast to the more common team structure of project managers, engineers, and engineering managers. Jeff Norris, an engineer from ThoughtWorks joins the show to discuss the idea of the tech lead.

This is a great show for anyone in management who is looking for alternative team structures, and this episode might also appeal to engineers who are looking to transition to a role with more variety.

", + "Episodes Title": "Tech Leadership with Jeff Norris", + "Episodes Uid": "SED9683902990", + "Episodes Audio File": "0584d23142682397fa8ee4ec64d3dbfb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ad", + "Episodes ID": "108bb768-e329-11ea-91a2-8bd62eda1144", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/slackbots_edited.mp3", + "Episodes Pubdate Date": "2016-11-16", + "Episodes Summary": "

Slack is a chat client that has reached wide adoption. The rise of Slack has coincided with the rise of chatbots. A chatbot is a simple, conversational interface into a computer program that may have simple functionality, like telling you some simple statistics, or more complex functionality, like helping you manage your continuous integration pipeline.

Bot design and engineering is a new field, and a vast array of resources and techniques are available for developers looking to hack on it. Amir Shevat is the director of developer relations at Slack, and is responsible for communicating with developers about the best ways to build bots for Slack.

After seeing his talk at O’Reilly Bot Day, I had a number of questions about where we are with bots today and where we are going. I enjoyed this conversation with Amir, and if you aren’t already convinced that bots are an important platform for engineers to understand, this conversation will convince you.

", + "Episodes Title": "Slack Bots with Amir Shevat", + "Episodes Uid": "SED3869222013", + "Episodes Audio File": "3ec5d5bed6a0da504a2b942527797700.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "28q", + "Episodes ID": "127b2e6e-e329-11ea-91a2-fbe536fce908", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/topicroundtable_edited.mp3", + "Episodes Pubdate Date": "2016-10-21", + "Episodes Summary": "

Bot fraud, the New York tech scene, RethinkDB and open source; these topics and more are discussed in today’s episode. Two of the most popular guests return to the show to explore a variety of topics.

Ben Halpern is the creator of The Practical Dev, a massively popular Twitter account and blog that you may recognize from its parody O’Reilly book covers. Haseeb Qureshi is an engineer at Airbnb, and a blogger who is well known for his writings on salary negotiation and coding boot camps.

This episode was an experiment–if you like it, please let me know what you think.

", + "Episodes Title": "Topic Roundtable with Haseeb Qureshi and Practical Dev’s Ben Halpern", + "Episodes Uid": "SED9363005181", + "Episodes Audio File": "b523576490cd89f96bd3e8f570613f0b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6g3", + "Episodes ID": "eb7da1f2-e328-11ea-91a2-8bc9a1bd9a30", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_22_DatadogGabrielJames.mp3", + "Episodes Pubdate Date": "2019-11-22", + "Episodes Summary": "

Web applications are used on a wide variety of platforms. 

On each of these platforms the web app needs to load properly and allow the user to navigate the website and interact with all of the user flows, such as sign-up, login, and the various read and write operations that make up the functionality of any website.

It is difficult to ensure web application functionality across all platforms, because there are so many platforms. Different operating systems, different underlying hardware, different browsers, and different device form factors all create potential sources of suboptimal website functionality and performance.

Testing web applications often involves the work of a manual quality assurance (QA) employee. The QA can simulate the procedures that a normal user would go through. This QA process ensures that the website is operating as expected. But the manual workflow can slow down software development.

Gabriel-James Safar is a software engineer and the founder of Madumbo, which was acquired by Datadog. Madumbo was founded with the goal of making web application testing simpler by identifying errors in pages and enabling users to create test suites from recordings of user activity. This process simplifies and accelerates the testing process. 

Gabriel-James joins the show to talk about his experience building Madumbo, and his perspective on the modern application testing process. Full disclosure: Datadog is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Web Application Testing with Gabriel-James Safar", + "Episodes Uid": "SED5473208972", + "Episodes Audio File": "01c1da4a033899571568983bce0b8927.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "19q", + "Episodes ID": "25fdd946-e329-11ea-91a2-fb4a9e1ac0d6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Rubyconf_Edited_2.mp3", + "Episodes Pubdate Date": "2016-01-12", + "Episodes Summary": "

Marty Haught is a director of Ruby Central, a nonprofit dedicated to the support and advocacy of the worldwide ruby community. Ruby Central also hosts the RubyConf and RailsConf software conferences.

", + "Episodes Title": "The Ruby Community with Marty Haught", + "Episodes Uid": "SED1600033258", + "Episodes Audio File": "bad5ce06feb2a564e9e86fa5cbd0a245.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6dm", + "Episodes ID": "ebc719cc-e328-11ea-91a2-f7acf68a863b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_31_FBFalloutAntonio.mp3", + "Episodes Pubdate Date": "2019-10-31", + "Episodes Summary": "

Chaos Monkeys is a book about Silicon Valley startups and Facebook. It is one of the most accurate books written about the modern technology industry, and captures both the negatives and the positives of software companies.

Antonio Garcia Martinez is the author of Chaos Monkeys. He wrote the book after going through a gauntlet of prototypical Silicon Valley experiences. Antonio founded an adtech company called AdGrok. His company was funded by the startup accelerator Y-Combinator, and during his time at the company there were many dramatic events that Antonio tells in great detail. AdGrok was acquired by Twitter, and Antonio went to work at Facebook on its ads platform.

Antonio is a fantastic writer. What makes Chaos Monkeys special is that it reads like a book written by an author who accidentally found himself in a technology career, rather than a technologist who opportunistically wrote a book.

Note: This episode contains explicit language.

", + "Episodes Title": "Facebook Fallout with Antonio Garcia Martinez", + "Episodes Uid": "SED4446389620", + "Episodes Audio File": "1a0bbdb17b2176a5c6c1dbff66a334c0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24z", + "Episodes ID": "16a9462e-e329-11ea-91a2-ab33ea544e89", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Apache_Beam__Edited.mp3", + "Episodes Pubdate Date": "2016-08-19", + "Episodes Summary": "

Unbounded data streams create difficult challenges for our application architectures. The data never stops coming, and we are forced to assume that we will never know if or when we have seen all of our data. Some streaming systems give us the tools to deal partially with unbounded data streams, but we have to complement those streaming systems with batch processing, in a technique known as the Lambda Architecture.
\nApache Beam is a unified model for defining and executing data processing workflows, and Frances Perry joins the show to explain how Beam provides a way for us to model our data processing, agnostic of whether we choose to run those workflows on Spark, Flink, or Google’s Dataflow.

", + "Episodes Title": "Apache Beam with Frances Perry", + "Episodes Uid": "SED8479884089", + "Episodes Audio File": "d1557a082544dfc986066aab0ff6b680.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6wm", + "Episodes ID": "ea4a418c-e328-11ea-91a2-83149e88160b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_04_BeginBrianLeRoux.mp3", + "Episodes Pubdate Date": "2020-03-04", + "Episodes Summary": "

Full-stack JavaScript applications have been possible since the creation of NodeJS in 2009. Since then, the best practices for building and deploying these applications have steadily evolved with the technology. 

ReactJS created consolidation around the view layer. The emergence of AWS Lambda created a new paradigm for backend execution. Serverless tools such as DynamoDB offer autoscaling abstractions. CDNs such as Cloudflare and Fastly can now do processing on the edge.

Brian LeRoux is the founder of Begin.com, a hosting and deployment company built on serverless tools. He’s also the primary committer to Architect, a framework for defining applications to be deployed to serverless infrastructure. Brian joins the show to talk about his work in the JavaScript ecosystem and his vision for Begin.com.

Brian is also speaking at Reactathon, a San Francisco JavaScript conference taking place March 30th and 31st in San Francisco. This week we will be interviewing speakers from Reactathon, and if you are interested in JavaScript and the React ecosystem then stay tuned, and if you hear something you like, you can check out the Reactathon conference in person.

", + "Episodes Title": "JavaScript Deployments with Brian LeRoux", + "Episodes Uid": "SED8425930572", + "Episodes Audio File": "420ef93c8f7114b548c4e0bb7e4663e6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25t", + "Episodes ID": "15932822-e329-11ea-91a2-57c67abc904b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Drones_with_Airware_Edited.mp3", + "Episodes Pubdate Date": "2016-09-05", + "Episodes Summary": "

Drones will become a central part of our lives. Drones are delivering packages, surveying cell phone towers, providing wi-fi, or fertilizing crops. Drones are assisting humans in dangerous work, and serving as an entirely new computing platform, providing services that were previously nonexistent.

Airware is a company that is building a full-stack drone platform. In this episode, Buddy Michini takes us through the software architecture of a drone. Airware’s drones have two operating systems–one for the real-time flight critical aspects and one for application developers who want to build their own software for drones.

", + "Episodes Title": "Drones with Buddy Michini", + "Episodes Uid": "SED1482855270", + "Episodes Audio File": "c7d0cae0fe56bb072c24afbdb56fbeb6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1rv", + "Episodes ID": "200720e2-e329-11ea-91a2-0b3d1cdf859d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Codenewbie_Edited.mp3", + "Episodes Pubdate Date": "2016-03-24", + "Episodes Summary": "

CodeNewbie is a community of programmers and people learning to code. There are so many people learning about software today, and CodeNewbie gives them a place to hang out, socialize, and become comfortable with the world of software. CodeNewbie has an excellent podcast, and if you like Software Engineering Daily you should check it out.

Saron Yitbarek is the guest today, she is the creator of CodeNewbie. In this episode of Software Engineering Daily, Saron sits down to talk about learning to code after she had already had several careers, spanning biology, public radio, and marketing.

", + "Episodes Title": "CodeNewbie with Saron Yitbarek", + "Episodes Uid": "SED8617530763", + "Episodes Audio File": "6efa630706f08b97aa8458fec57e44a8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "21f", + "Episodes ID": "1a36c55a-e329-11ea-91a2-d7a9a1b85c92", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Transferwise_Edited.mp3", + "Episodes Pubdate Date": "2016-06-30", + "Episodes Summary": "

Transferring money from one country to another is expensive, and the banks that facilitate money transfer have tricked us into believing that it should be expensive. On today’s show, Harsh Sinha explains the peer-to-peer system of transferring money with TransferWise, where he works as VP of engineering.
\nHarsh also discusses the larger picture of FinTech companies. The emergence of so many companies at the intersection of finance and technology is no accident. The 2008 financial crisis created a loss of trust in the existing financial system. Simultaneously, smart phones and cheap cloud computing has created opportunities for newer companies like TransferWise to position themselves as a new option for consumer banking.

", + "Episodes Title": "P2P Money Transfer with TransferWise’s Harsh Sinha", + "Episodes Uid": "SED6293655286", + "Episodes Audio File": "0a602f5bae2b48ca55eb4b710cac6cce.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "67d", + "Episodes ID": "ec4f3578-e328-11ea-91a2-db5e78d270d5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_20_ReadMeGregKoberger.mp3", + "Episodes Pubdate Date": "2019-09-20", + "Episodes Summary": "

A software company needs to get many things right in order to be successful. Having a useful product with solid engineering is only the beginning.

ReadMe was started five years ago. The company solved a seemingly simple problem: documentation for software products. If you have worked as a software engineer, you have looked at documentation. You know that there is a wide range of quality among the documentation that exists for different software products.

ReadMe solved the problem of documentation-as-a-service, and it solved the problem better than any other company in the market. But after building a great business around documentation, the direction in which to take the business was unclear. 

How do you expand a documentation software business? Should you start building API management systems? Should you build lead generation tools? Should you try to sell products to developer evangelists?

Greg Koberger is the CEO of ReadMe, and he joins the show to talk about the business, the strategy, and the fundraising process for ReadMe. Greg was previously on the show very early on, and he stood out as a guest that was remarkably friendly and willing to talk about a wide range of topics. In the previous show with Greg, he was one year into his business. Today, it has been five years since ReadMe was started, and we catch up on how his business has evolved since our first interview.

ReadMe had become a profitable business very early in its life. In Silicon Valley, a quickly profitable business is the exception. Rather than structuring the finances of ReadMe with the expectation of successive funding rounds every 18-24 months, Greg took a slower approach. His company grew at a rate that was affordable while maintaining that profitability.

While ReadMe maintained profitability from its core product of documentation software, Greg patiently thought about what product to build next within the company. A software company will typically expand into adjacent markets, or offer products that their current users are willing to pay additional money for. 

Eventually, ReadMe found its second product: developer metrics. Greg and his team figured out that gathering metrics around how APIs are being consumed has synergies with the core ReadMe product. With a second product, ReadMe was now able to forecast significant growth. The company also gained an incentive to raise money. 

With additional money, ReadMe would be able to deepen the developer metrics product, hire a bigger team, and think much bigger than they would have been able to as a single-product company with a smaller total addressable market. ReadMe raised a series A from Accel, one of the most respected venture capital firms in the business, and the company is now entering a new period in its development.

ReadMe is a fascinating case study in balancing ambition with financial discipline at a software company.

", + "Episodes Title": "ReadMe with Greg Koberger", + "Episodes Uid": "SED9577971537", + "Episodes Audio File": "a49d2cbc0c29039b8fa8445631764166.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6a7", + "Episodes ID": "ec0eab5c-e328-11ea-91a2-d3122aeaca44", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_10_DataVisualization.mp3", + "Episodes Pubdate Date": "2019-10-10", + "Episodes Summary": "

Data visualization is the presentation of data in a way that emphasizes certain qualities about that data.

Data visualization can be used to prove a specific point, or it can be used as a depiction of a data set to be explored. Data visualization is used in consumer software products as well as backend engineering systems such as logging data.

As tools for data visualization have improved, data applications can consume more data at a faster pace. Browsers and mobile phones have improved, giving us the power to render high fidelity, complex visualizations in near-real time.

Sherman Wood and Chad Lumley are engineers working on Jaspersoft, an embedded analytics tool from TIBCO. Embedded analytics is a type of software that allows for the creation of data visualizations inside of an application. Sherman and Chad join the show to discuss techniques for data visualization and how the field has evolved.

Full disclosure: TIBCO is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Data Visualization with Sherman Wood and Chad Lumley", + "Episodes Uid": "SED5065316710", + "Episodes Audio File": "bb5ed42bab4ccb10fa0a9e6f009f7b32.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "0e06f7dc-f92c-11ea-b2a0-f71477f179dc", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-18", + "Episodes Summary": "


", + "Episodes Title": "Enterprise Investing with Ed Sim", + "Episodes Uid": "SED7339649456", + "Episodes Audio File": "cd2014901bc1e2c580df3e974246b457.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "22a", + "Episodes ID": "1a09580e-e329-11ea-91a2-d3f48aa2f6c1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Pindrop_Edited.mp3", + "Episodes Pubdate Date": "2016-07-06", + "Episodes Summary": "

Call centers are a vulnerable point of attack for large enterprises. Fraud accounts for more than $20 billion in lost money every year, and a significant portion of that fraud is due to customer service representatives being fraudulent social engineering attacks.

Chris Halaschek joins the show today to discuss how Pindrop Security is addressing this attack vector. Every phone call that gets made to a call center has a unique phoneprint, and the machine learning model at Pindrop Security uses these phoneprints to assign a risk score to each call. Chris also discusses the challenges associated with scaling a cloud security company.

", + "Episodes Title": "Security and Machine Learning in the Call Center with Pindrop Security’s Chris Halaschek", + "Episodes Uid": "SED4615520656", + "Episodes Audio File": "184666f76a6b3381b426b75a1a235ce3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6vp", + "Episodes ID": "ea5a66ca-e328-11ea-91a2-abc9c3f12170", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_28_SlackServiceWorkers.mp3", + "Episodes Pubdate Date": "2020-02-27", + "Episodes Summary": "

Slack is a messaging application with millions of users. The desktop application is an Electron app, which is effectively a web browser dedicated to running Slack. This frontend is built with ReactJS and other JavaScript code, and the application is incredibly smooth and reliable, despite its complexity.

When a user boots up Slack, the application needs to figure out what data to fetch and where to fetch it from. Companies that use Slack heavily have thousands of messages in their history, and Slack needs to determine which of those should be pulled into the client. There are profile images, and logos, and custom emojis, all of which are used to define the user’s custom workspace experience.

Anuj Nair joined Slack in late 2017. In the years since he has been with the company, Anuj helped rewrite the Slack frontend client, including work on the bootup experience, the caching infrastructure, and the role of service workers. Anuj joins the show to discuss his work on the Slack frontend architecture and the canonical view layer problems that Slack faces.

", + "Episodes Title": "Slack Frontend Architecture with Anuj Nair", + "Episodes Uid": "SED9464928576", + "Episodes Audio File": "053b3a744a056ac369d90faceca860d8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6xm", + "Episodes ID": "ea2dab26-e328-11ea-91a2-cb5061fa8822", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_12_FlyteLyftScheduling.mp3", + "Episodes Pubdate Date": "2020-03-12", + "Episodes Summary": "

Lyft is a ridesharing company that generates a high volume of data every day. 

This data includes ride history, pricing information, mapping, routing, and financial transactions. The data is stored across a variety of different databases, data lakes, and queueing systems, and is processed at scale in order to generate machine learning models, reports, and data applications.

Data workflows involve a set of interconnected systems such as Kubernetes, Spark, Tensorflow, and Flink. In order for these systems to work together harmoniously, a workflow manager is often used to orchestrate them together. A workflow platform lets a data engineer have a high-level view into how data moves through the system, and can be used to reason about retries, resource utilization, and scalability.

Flyte is a data processing system built and open-sourced at Lyft. Allyson Gale and Ketan Umare work at Lyft, and they join the show to talk about how Flyte works, and why they needed to build a new workflow processing system when there are already tools available such as Airflow.

", + "Episodes Title": "Flyte: Lyft Data Processing Platform with Allyson Gale and Ketan Umare", + "Episodes Uid": "SED7271421617", + "Episodes Audio File": "9c284bac20d90a255516d1b75f6ae2c0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 228, + "Episodes ID": "1a1e7c34-e329-11ea-91a2-7f8a7d1e731e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/KubeCloud_Edited.mp3", + "Episodes Pubdate Date": "2016-07-04", + "Episodes Summary": "

At most universities, there is not a course titled “cloud computing”. Most students leave college without an understanding of distributed systems, cloud service providers, and the fundamentals of how a data center works. Kasper Nissen and Martin Jensen are changing that with KubeCloud, a small tangible cloud computing cluster that runs on Raspberry Pis.

Kasper and Martin started KubeCloud as a masters thesis, and it is grown to a textbook-sized treatise on cloud computing. KubeCloud is both software and a curriculum to teach students microservices, containers management, and the real-world problems of distributed systems.

", + "Episodes Title": "KubeCloud: Tangible Cloud Computing with Kasper Nissen and Martin Jensen", + "Episodes Uid": "SED3016470364", + "Episodes Audio File": "02e39cf35e34f028f04efdbe5ebd27bb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6lx", + "Episodes ID": "eaef1c70-e328-11ea-91a2-eb3445c84a8a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_16_JSParty.mp3", + "Episodes Pubdate Date": "2020-01-16", + "Episodes Summary": "

The JavaScript ecosystem stretches across frontend, backend, and middleware. There are newer tools such as GraphQL, Gatsby, and WebAssembly. There are frameworks like React, Vue, and Angular. There is complex data handling with streams, caches, and TensorFlow.js.

JavaScript is unlike any other ecosystem, because a single language can be used to construct every part of an application. Because JavaScript is used for such a broad spectrum of use cases, the amount of tooling available can be intimidating to someone new to the ecosystem.

Kevin Ball is a host of JS Party, a podcast on The Changelog network. Kevin joins the show to give his perspective on the JavaScript ecosystem. We discussed ES Modules, the JAM Stack, and the growing number of tools, libraries, and workflows used by JavaScript developers.

", + "Episodes Title": "JS Party with Kevin Ball", + "Episodes Uid": "SED3012000430", + "Episodes Audio File": "c1d53db1fe1f3c9719e96734821c1d9d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "71r", + "Episodes ID": "e9e3b066-e328-11ea-91a2-3f40f7438ee4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_03_V8Lite.mp3", + "Episodes Pubdate Date": "2020-04-03", + "Episodes Summary": "

V8 is the JavaScript engine that runs Chrome. Every popular website makes heavy use of JavaScript, and V8 manages the execution environment of that code. The code that processes in your browser can run faster or slower depending on how “hot” the codepath is. If a certain line of code is executed frequently, that code might be optimized to run faster.

V8 is running behind the scenes in your browser all the time, evaluating the code in your different tabs and determining how to manage that runtime in memory. As V8 is observing your code and analyzing it, V8 needs to allocate resources in order to determine what code to optimize. This process can be quite memory intensive, and can add significant overhead to the memory overhead of Chrome.

Ross McIlroy is an engineer at Google, where he worked on a project called V8 Lite. The goal of V8 Lite was to significantly reduce the execution overhead of V8. Ross joins the show to talk about JavaScript memory consumption, and his work on V8 Lite. We have done some great shows on JavaScript in the past, which you can find on SoftwareDaily.com. Also, if you are interested in writing about JavaScript, we have a new writing feature that you can check out by going to SoftwareDaily.com/write.

", + "Episodes Title": "V8 Lite with Ross McIlroy", + "Episodes Uid": "SED6092866226", + "Episodes Audio File": "e1c99284e87cded9ea8fce944e88f70b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23c", + "Episodes ID": "187618d8-e329-11ea-91a2-03ac6247c2b7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/untapt_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-07-28", + "Episodes Summary": "

Financial technology has changed significantly in the last decade, and companies both new and old are adapting to that change.

Newer companies like TransferWise and Stripe are often called “fintech” companies–short for “financial technology”. Established companies like banks may not refer to themselves as fintech companies, but the way that they do business is changing, due to technological advances like blockchain.

Ed Donner is the CEO of untapt, a hiring platform for fintech companies, and he joins the show to talk about the fundamental changes that are causing so many new fintech companies to be created. Before starting untapt, Ed worked at JP Morgan Chase, where he spent much of his time leading engineers and hiring engineers, which makes him well-equipped to build a platform for hiring software engineers into fintech companies, driven by machine intelligence.

", + "Episodes Title": "Fintech Hiring with Ed Donner", + "Episodes Uid": "SED7538467788", + "Episodes Audio File": "0b484b9364b710b6d14a734ad552aeda.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "yq", + "Episodes ID": "2c4b9c70-e329-11ea-91a2-e75ce8678dce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Mothercoders.mp3", + "Episodes Pubdate Date": "2015-11-16", + "Episodes Summary": "

MotherCoders is a program that helps mothers gain technical skills with the support of a community and benefits like on-site childcare.

Tina Lee is the Founder of MotherCoders, having created the program to meet her own need after trying to find existing support systems while learning how to code.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "MotherCoders with Tina Lee", + "Episodes Uid": "SED7012991358", + "Episodes Audio File": "f3f1854015fc71548aefcc346fabfe3b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 255, + "Episodes ID": "16286c16-e329-11ea-91a2-cb4094706e5c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/sheriff_mohamed_fixed_edited.mp3", + "Episodes Pubdate Date": "2016-08-25", + "Episodes Summary": "

Kubernetes is a cluster management tool open sourced by Google. On Software Engineering Daily, we’ve done numerous shows on how Kubernetes works in theory. Today’s episode is a case study in how to deploy Kubernetes to production at a company with existing infrastructure.

GolfNow is a fifteen year-old application written in C# .NET. It is a successful, growing business that is a division of NBC Sports. As GolfNow has grown, it has encountered scalability issues, and the engineering team at GolfNow decided to move its entire monolithic infrastructure to microservices running in Docker containers, managed by Kubernetes.
\nSheriff Mohamed joins the show today to discuss migrating his company’s application to Kubernetes. It’s a great show for anyone who is moving a large team to Kubernetes, or considering the technology for their application.

", + "Episodes Title": "Kubernetes Migration with Sheriff Mohamed", + "Episodes Uid": "SED9918877927", + "Episodes Audio File": "44e147c0aaf82d4665b874773960f354.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1v6", + "Episodes ID": "1f006cc6-e329-11ea-91a2-7f86622de8c5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/oss_nadia_music.mp3", + "Episodes Pubdate Date": "2016-04-09", + "Episodes Summary": "


\nNadia Eghbal joins us as the host of today’s show to discuss the past, present, and future of open-source software. This monologue was adapted from Nadia’s article, We’re in a brave, new post open source world.

In this episode, Nadia describes the origins of open-source in the Free software movement, its rise to popularity, and today’s golden era where mainstream and popular technologies like React, Spark and Docker are all open source projects.

Yet there are several serious issues that threaten the foundation upon which the current open-source renaissance is happening. Nadia discusses what these are, and how to resolve these issues so that we can continue to have a vibrant ecosystem for developers.

Thank you to Nadia Eghbal for coming on the show and for standing up for open source software.

", + "Episodes Title": "The Past, Present, and Future of Open Source", + "Episodes Uid": "SED2953986769", + "Episodes Audio File": "a1b5abd92cf689a230445c85232c9c86.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3c4", + "Episodes ID": "f5176a04-e328-11ea-91a2-cf0b434d2a7b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ml_techdebt_ad_free.mp3", + "Episodes Pubdate Date": "2017-12-25", + "Episodes Summary": "

Originally published November 17, 2015

Technical debt, referring to the compounding cost of changes to software architecture, can be especially challenging in machine learning systems.

D. Sculley is a software engineer at Google, focusing on machine learning, data mining, and information retrieval. He recently co-authored the paper Machine Learning: The High Interest Credit Card of Technical Debt.

", + "Episodes Title": "Machine Learning and Technical Debt with D. Sculley Holiday Repeat", + "Episodes Uid": "SED8547534931", + "Episodes Audio File": "167e4accf829ebe48db453a4ab4a54ec.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2eq", + "Episodes ID": "0b302646-e329-11ea-91a2-57a6b6bf1cbb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/freecodecamp_arch_fixed.mp3", + "Episodes Pubdate Date": "2017-01-12", + "Episodes Summary": "

Free Code Camp is an online learning platform that takes people from knowing nothing about code to having enough knowledge to build software for a living. We have already done a show with Quincy Larson, the founder of Free Code Camp, in which we discussed his motivation for starting the organization.

The economics of running a free interactive platform with thousands of users informs the architectural strategy. Free Code Camp does not even have ads, so it needs to be frugal. Berkeley Martinez is the CTO of Free Code Camp, and in today’s episode he discusses how Free Code Camp works from a technical perspective, including how the site’s sandboxed coding environment is built.

", + "Episodes Title": "Architecture of Free Code Camp with Berkeley Martinez", + "Episodes Uid": "SED4145703755", + "Episodes Audio File": "dc884d3bc89565d994bcab8e14e4db25.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1up", + "Episodes ID": "1f225890-e329-11ea-91a2-1f409dcf074c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/git_workflows_edited.mp3", + "Episodes Pubdate Date": "2016-04-07", + "Episodes Summary": "

Git is the most popular version control system. If you have been programming for less than a decade, it’s likely that you haven’t used any other method of version control. The git workflow of a software team defines how that team collaborates, builds, and ships software.

Tim Pettersen is a developer advocate at Atlassian, where he has been building software around git for many years. He joins us on today’s episode to talk about strategies for git–including branching, merging, continuous integration, and software as a service.

", + "Episodes Title": "Git Workflows with Tim Pettersen", + "Episodes Uid": "SED5149340419", + "Episodes Audio File": "fe6f5bfa033ea56a18dab548bd61dda7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 213, + "Episodes ID": "1ab6aa90-e329-11ea-91a2-ef3602cc1027", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Serverless_Code_Edited.mp3", + "Episodes Pubdate Date": "2016-06-21", + "Episodes Summary": "

The unit of computation has evolved from on premise servers to virtual machines in the cloud to containers running in those virtual machines. Serverless computation is another stage in the evolution of computational unit management. With a serverless architecture, a function call to the cloud spins up a transient container, calls the function on that container, and then spins down the container.

Ryan Scott Brown joins the show today to discuss the benefits and consequences of serverless computing. With containers and VMs, we still have to worry that the resources we are spinning up in the cloud will run without being utilized. Serverless computing gives us more control over these compute resources, so that we don’t have unused servers that we are paying for.

", + "Episodes Title": "Serverless Code with Ryan Scott Brown", + "Episodes Uid": "SED6098841043", + "Episodes Audio File": "b8e19c344e3876d472fe60a447f96b92.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xa", + "Episodes ID": "ed61c8ea-e328-11ea-91a2-ab647bd4a980", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/you_are_not_a_commodity_keynote.mp3", + "Episodes Pubdate Date": "2019-07-07", + "Episodes Summary": "

Today’s episode is a keynote I gave at Full Stack Tech Radar Day in Tel Aviv. The talk is called “You Are Not a Commodity”.

This talk is also available as a YouTube video.

The slides can be accessed here.

The world of commodity engineering is coming to an end. Developers are becoming more productive, more flexible, and more entrepreneurial. How does this impact you as an engineer? And how does it impact large companies who need a fungible set of engineers to maintain their software?

", + "Episodes Title": "You Are Not A Commodity (Keynote at Tikal Full Stack Tech Radar Day)", + "Episodes Uid": "SED4687569401", + "Episodes Audio File": "16f94f50aea81c6a941e96c7ee184efe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "38k", + "Episodes ID": "f5890ae2-e328-11ea-91a2-8765dedbac3a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/IncidentResponse.mp3", + "Episodes Pubdate Date": "2017-11-21", + "Episodes Summary": "

As a system becomes more complex, the chance of failure increases. At a large enough scale, failures are inevitable. Incident response is the practice of preparing for and effectively recovering from these failures.

An engineering team can use checklists and runbooks to minimize failures. They can put a plan in place for responding to failures. And they can use the process of post mortems to reflect on a failure and take full advantage of the lessons of that failure.

Emil Storlarsky is a production engineer at Shopify where his role shares many similarities with that of Google’s site reliability engineers. In this episode, Emil argues that the academic study of emergency management and industries such as aerospace and transportation have a lot to teach software engineers about responding to production problems.  

In this interview with guest host Adam Bell, Emil argues that we need to move beyond tribal knowledge and incorporate practices such as an incident command system and rigorous use of checklists. Emil suggests that we need to move beyond a mindset of “move fast and break things” and toward a place of more deliberate preparation.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

Incident Response Insights Talk

The Human Side Of Post Mortems

", + "Episodes Title": "Incident Response with Emil Storlarsky", + "Episodes Uid": "SED3212016565", + "Episodes Audio File": "774ba0baab21f33dda1221f0708e3934.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3c7", + "Episodes ID": "f51326ec-e328-11ea-91a2-fb830053cac0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/wolfram_ad_free.mp3", + "Episodes Pubdate Date": "2017-12-26", + "Episodes Summary": "

Originally published November 10, 2015

Wolfram Research makes computing software powered by the Wolfram language, a knowledge-based programming language that draws from symbolic and functional programming paradigms.

Stephen Wolfram is the Founder and CEO of Wolfram Research, and also the author of A New Kind of Science.

", + "Episodes Title": "Knowledge-Based Programming with Stephen Wolfram Holiday Repeat", + "Episodes Uid": "SED4131346420", + "Episodes Audio File": "5f5c41959d062997b90ad7d417b1fcc1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4to", + "Episodes ID": "f0cad5da-e328-11ea-91a2-8f74907b2032", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/GigEconomyEpisode.mp3", + "Episodes Pubdate Date": "2018-10-28", + "Episodes Summary": "

I like to write music, and a year ago I started working on an album called “Gig Economy”. The plan for the album was to hire musicians from gig economy platforms like Fiverr and Upwork to perform on songs that I produced.

The album is finished and I’m happy with the result, so I’m sharing it on the podcast today as an extra episode released on a Sunday. We’ll be back tomorrow with content about software engineering.

Writing this album made me think about the future of work. I love music, but I am not a professional musician. I take the craft seriously, but perhaps not as seriously as someone who has made music their full-time career. I’ve never taken the time to network with musicians and develop collaborative relationships.

The gig economy allowed me to pay creative people to collaborate with me. The transactional nature of my relationship with the collaborators meant that both of us had the incentive structure to work effectively. This improved quality and kept the pace of the project moving quickly.

Today, the gig economy is widely regarded as a mode of work that removes individuality. Critics of the gig economy say that it turns workers into a commodity. If you use Uber, you aren’t thinking about the human who is driving you. As long as your driver has a high rating, you are satisfied.

My experience producing this album with gig economy musicians showed a different side of our new employment systems.

I found artists who I deeply enjoyed working with. There was no ambiguity about our relationship. Nobody was flaky. I paid these collaborators well, and in return they helped me fulfill an artistic vision.

Without gig economy platforms, I could not have written this album.

The gig economy is a playground for creativity. If you want to get paid to work as an artist, you can do so as long as you have a laptop. If you are a corporate worker making a good salary, but you spend your weekend producing art, you can pay artists to help you complete your vision.

The greatest works of art are often the result of a talented workforce directed by an established leader. The gig economy lets you become a leader and recruit a team of creative, proven artists in a single day.

I hope you enjoy “Gig Economy”. If you would rather listen on Spotify or YouTube, links are below.

If you like the album, please share it on Twitter or Facebook. If you listened all the way through and have feedback for me, I’d love to know your thoughts. You can send me a tweet @the_prion or an email: jeff@softwareengineeringdaily.com

", + "Episodes Title": "Gig Economy", + "Episodes Uid": "SED4860695251", + "Episodes Audio File": "c8960011b9f649e63f94051210bd03a3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 248, + "Episodes ID": "179927fc-e329-11ea-91a2-23f64ab97be5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Clojure_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-08-04", + "Episodes Summary": "

Clojure is a dynamically typed functional language that runs on the JVM. Today’s guest Alex Miller gives us an overview of Clojure’s core functionality. Alex is a developer of Cognitect, and a founder of the the Strange Loop conference.

We discuss the data structures, garbage collection, and concurrency support. How does Clojure compare to other JVM languages like Scala and Groovy? How does Clojure copy immutable data structures without copying all of the data? How does a Clojure program get evaluated and converted to Java bytecode? These questions, and many others are discussed in this episode.

", + "Episodes Title": "Clojure with Alex Miller", + "Episodes Uid": "SED1464791202", + "Episodes Audio File": "a4fc3b171f8081ec749ebacc2f757bca.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2u7", + "Episodes ID": "f7a5a786-e328-11ea-91a2-8b64e30458cb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ReactNativeNader.mp3", + "Episodes Pubdate Date": "2017-07-06", + "Episodes Summary": "

React Native allows developers to reuse components from one user interface on multiple platforms. React Native was introduced by Facebook to reduce the pain of teams who were rewriting their user interfaces for web, iOS, and Android.

Nader Dabit hosts React Native Radio, a podcast about React Native. Nader also trains companies to user React Native through his company React Native Training. In this episode, we explore what a developer can and cannot do with React Native, when a developer needs to use native APIs, and some speculation on the future of React Native.

This episode is a good preface for tomorrow’s episode about React Native Interfaces with Leland Richardson of Airbnb. In that episode we will dive deeper into how React Native works and just how big of a change it could be for cross-platform developers.

Check out our new topic feeds, in iTunes or wherever you find your podcasts. We’ve sorted all 500 of our old episodes into categories like business, blockchain, cloud engineering, JavaScript, machine learning, and greatest hits. Whatever specific area of software you are curious about, we have a feed for you. Check the show notes for more details.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "React Native Ecosystem with Nader Dabit", + "Episodes Uid": "SED3283344573", + "Episodes Audio File": "75ca90b1ee9e53a490afcc68cbea594e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1u3", + "Episodes ID": "1f573cc2-e329-11ea-91a2-6b416cad81fc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/uber_danny_edited.mp3", + "Episodes Pubdate Date": "2016-04-04", + "Episodes Summary": "

Uber is a transportation company with a high volume of temporal spacial data, constantly being collected from the devices of its users. At any given time, the engineers and data scientists at Uber need to be able to query the system, and understand what is going on with drivers and riders.

The unique real-time engineering requirements of Uber lead to an interesting architecture. Danny Yuan joins us today to discuss Uber’s data engineering stack and how the company makes use of its streaming data.

", + "Episodes Title": "Stream Processing at Uber with Danny Yuan", + "Episodes Uid": "SED7439077735", + "Episodes Audio File": "ba625c66a54515d84d55e15bff72371a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "yy", + "Episodes ID": "2c1d5964-e329-11ea-91a2-db1e4909e8a0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Tech_Debt_Edited.mp3", + "Episodes Pubdate Date": "2015-11-17", + "Episodes Summary": "

Technical debt, referring to the compounding cost of changes to software architecture, can be especially challenging in machine learning systems.

D. Sculley is a software engineer at Google, focusing on machine learning, data mining, and information retrieval. He recently co-authored the paper Machine Learning: The High Interest Credit Card of Technical Debt.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Machine Learning and Technical Debt with D. Sculley", + "Episodes Uid": "SED9178824148", + "Episodes Audio File": "4963bfbf837c336cc7d9c1357733a5f9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25v", + "Episodes ID": "1574378c-e329-11ea-91a2-5300b36d17b6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Recurse_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-09-07", + "Episodes Summary": "

Learning to program is about self-driven exploration. Universities help guide you, coding boot camps provide a rigorous environment to work in, and online coding courses provide content for you to study. But none of this will turn you into a great programmer unless you have the drive to improve and the curiosity to explore.

The Recurse Center is a place where people can come to become better programmers. Nick Bergson-Shilcock is a founder of The Recurse Center and he joins the show to discuss how it works and why he started it.
\nThis episode is a continuation of our exploration of coding boot camps, online courses, and universities, which are the pillars of programming education. The Recurse Center presents another unique model for improving as a programmer.

", + "Episodes Title": "The Recurse Center with Nick Bergson-Shilcock", + "Episodes Uid": "SED1935490811", + "Episodes Audio File": "b822ab3cf69a8019c12009de9531b967.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1zh", + "Episodes ID": "1c5d6b0e-e329-11ea-91a2-23ab3cecf45e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/rust_edited.mp3", + "Episodes Pubdate Date": "2016-05-25", + "Episodes Summary": "

Rust is a systems programming language being developed at Mozilla. Rust has features of a high-level functional language like Scala and a low-level, performance-driven language like C++.

Steve Klabnik is a developer program member with Mozilla. In this episode, he discusses how Rust looks at memory management, type safety, mutability, and concurrency. We also dive into a discussion of the low level virtual machine, also known as the LLVM, which the language Swift is built on.

", + "Episodes Title": "Rust with Steve Klabnik", + "Episodes Uid": "SED4044773835", + "Episodes Audio File": "83600dcfdafffa22bd19e8e4ce0591a1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1uc", + "Episodes ID": "1f46626c-e329-11ea-91a2-db291f4cd6c5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/bithound_edited_with_pre.mp3", + "Episodes Pubdate Date": "2016-04-05", + "Episodes Summary": "

Code analysis tools can help a developer understand code. One tool for code analysis is bitHound, which provides code and dependency analysis for NodeJS applications. On today’s episode, we discuss how to use a code analysis tool–and we also talk about how to build one, by breaking down the distributed architecture of bitHound’s backend.

", + "Episodes Title": "Code Analysis with Dan Silivestru and Gord Tanner", + "Episodes Uid": "SED7852542754", + "Episodes Audio File": "f0ff7b3511674201e523c5eb0f89fcb1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 257, + "Episodes ID": "16591618-e329-11ea-91a2-db1144b8c15c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/distributed_tracing_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-08-24", + "Episodes Summary": "

In a microservices architecture, a user request will often make its way through several different services before it returns a result to the end user. If a user experiences a failed request, the root cause could be in any of the services along that request path. Even more problematic is the challenge of debugging latency in this kind of request chain.

Reshmi Krishna joins the show today to discuss distributed tracing, the process of tracking the path of a request through multiple services in order to determine the root cause of latency or errors. A popular tool for distributed tracing is Zipkin, which is largely based off of a paper published by Google called “Dapper”.

Reshmi is also speaking at the upcoming O’Reilly Velocity Conference in New York, September 20-22, so check that out if you are interested in web performance, continuous delivery, or anything else related to web and mobile development.

", + "Episodes Title": "Distributed Tracing with Reshmi Krishna", + "Episodes Uid": "SED2123927723", + "Episodes Audio File": "97dd382fa98f11bc945f1d4d74d6d579.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "36j", + "Episodes ID": "f5d594de-e328-11ea-91a2-d3c2b21fc900", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Avi_Networks_complete_with_preamble.mp3", + "Episodes Pubdate Date": "2017-10-31", + "Episodes Summary": "

Computational load is the amount of demand that is being placed on a computer system. “Load” can take the form of memory, CPU, network bandwidth, disk space, and other finite resources.

When we design systems, we need to prepare for high-load events. On a social network, people are much more active in the mornings. On an e-commerce site, Black Friday causes many more users to come online for discount shopping. Our distributed application must be able to scale in response to these spikes in traffic.

Cloud computing has changed the popular software architecture patterns, and load balancing has changed along with it. With on-demand, infinite infrastructure, we don’t need to worry about ordering servers and provisioning. With infrastructure as code, it becomes simpler to manage lots of deployable units–so we can break up our monolith into microservices, and have hundreds or thousands of virtual machines or containers running.

Enterprises that were started before cloud computing have large on-premise server deployments–but today, many of them also use the cloud. The cloud can be used to augment their classic on-prem deployments with cloud platform-as-a-service features. The cloud can also be used as a reliable way to scale during high load events.

Today, a common architectural pattern is to have your application broken up into services. Each of those services has multiple instances. When the load on a particular service is under lots of demand, you create more instances to handle the increased load. How do you monitor the load on each service? How do you know when to spin up new instances of the service?

Load analysis and load balancing across different services can be implemented by placing “agents” throughout your infrastructure. These agents gather data about services and service instances, and route that data to a centralized place. The centralized “control plane” can be used to make decisions about load-balancing and traffic routing.

Ranga Rajagopalan worked on networking at Cisco for a decade before co-founding Avi Networks as CTO. Avi Networks builds modern load balancing software, and in today’s episode, Ranga describes the requirements of load balancing. We talked about the evolution of network infrastructure, the impact of the cloud, and the technical decisions that his team has made when architecting Avi Networks. Full disclosure: Avi Networks is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Elastic Load Balancing with Ranga Rajagopalan", + "Episodes Uid": "SED8298460955", + "Episodes Audio File": "8de8c6c3f557e4e9f2e082cbaad8b049.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 615, + "Episodes ID": "ecd4cd0a-e328-11ea-91a2-0ff21be82386", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_10_ElegantPuzzleVirtualBookClub.mp3", + "Episodes Pubdate Date": "2019-08-11", + "Episodes Summary": "

In this episode Will Larson, author of An Elegant Puzzle: Systems of Engineering Management, speaks with Uma Chingunde of Stripe and Jeff Meyerson of Software Engineering Daily about engineering management. Will was also featured on SE Daily recently.

An Elegant Puzzle is an excellent resource on management techniques and strategies for scaling software organizations. Will’s writing draws from his experiences working at Uber and Stripe.

", + "Episodes Title": "An Elegant Puzzle Virtual Book Club", + "Episodes Uid": "SED1343477756", + "Episodes Audio File": "7d7f388b3fee0ba8e855407ffca6d3a3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "wa", + "Episodes ID": "2dc7a6de-e329-11ea-91a2-bf5949b27121", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Erlang_Edited.mp3", + "Episodes Pubdate Date": "2015-11-02", + "Episodes Summary": "

Erlang is a functional, concurrent programming language that was originally designed within Ericsson in the 1980’s. It was built to support distributed, fault-tolerant, non-stop applications suitable for telecommunications infrastructure.

Joe Armstrong is one of the designers of Erlang, and the chief architect of the Open Telecom Platform (OTP), a framework for building Erlang applications.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Erlang with Joe Armstrong", + "Episodes Uid": "SED6757741118", + "Episodes Audio File": "26a3c3c607907821cec617a22f6571cf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "qb", + "Episodes ID": "301953d8-e329-11ea-91a2-e30c7f8ee1b2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/greg_readme.mp3", + "Episodes Pubdate Date": "2015-10-08", + "Episodes Summary": "

ReadMe is simplifying the process of writing documentation. The platform provides a readymade developer hub with the ability to integrate API endpoints into documentation.

Greg Koberger is a developer and designer, and the founder of ReadMe. He previously founded a traveling incubator and worked for Mozilla.

", + "Episodes Title": "Rethinking Documentation with Greg Koberger", + "Episodes Uid": "SED2878364013", + "Episodes Audio File": "87af6266d6db1899ce1f6c739b7b72e9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "26b", + "Episodes ID": "152ea4ec-e329-11ea-91a2-b7a9f2e0a26b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/MSFT_Legal_edited.mp3", + "Episodes Pubdate Date": "2016-09-13", + "Episodes Summary": "

Microsoft was the dominant technology company in the 1990’s, until it came under fire for anticompetitive practices. Internet Explorer was tightly coupled to the Windows operating system, which prevented Netscape Navigator–a competing browser–from reaching users on the dominant platform.

This episode is about antitrust–what businesses can and cannot do in the name of competition, what the impact of Microsoft’s legal battles in the late 90’s was, and how the law might respond to potential technology monopolies in the near future–such as Facebook, Google, and Uber.


\nOur guest Harry First is a professor of law at New York University School of Law. He wrote a textbook called “The Microsoft Antitrust Cases: Competition Policy for the Twenty-First Century”.Sponsors

", + "Episodes Title": "Microsoft Antitrust with Harry First", + "Episodes Uid": "SED9322314995", + "Episodes Audio File": "7ce4550d348dbc363063c64d92e2c3f5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "sa", + "Episodes ID": "2faa9b82-e329-11ea-91a2-a3dd22805ccb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/genie_tomgianos.mp3", + "Episodes Pubdate Date": "2015-10-13", + "Episodes Summary": "

Genie is an open-source tool that provides job and resource management for the Hadoop ecosystem in the cloud.

Tom Gianos is a Senior Software Engineer at Netflix focusing on its big data platform. He is one of the core contributors in charge of maintaining and improving Genie.

", + "Episodes Title": "Netflix Genie with Tom Gianos", + "Episodes Uid": "SED5764639760", + "Episodes Audio File": "f48cd5e2a683ecf633ad78f165611f39.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1zx", + "Episodes ID": "1bd6976e-e329-11ea-91a2-8fb87925c8f7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Citus_Data.mp3", + "Episodes Pubdate Date": "2016-06-02", + "Episodes Summary": "

Ten years ago, databases were much simpler. Most companies would only have one or two types of databases in production. Today, the age of one-size-fits-all is over. Companies have multiple databases to deal with different types of use cases, and databases have become distributed to multiple nodes in order to be scalable.

Ozgun Erdogan of Citus Data joins the show to give us a modern look at databases. Ozgun suggests that PostgreSQL alone can perform most of the work that we are trying to get from our variety of databases. We discuss how Citus Data scales Postgres, and Ozgun contrasts an all-Postgres architecture with other types of databases such as the “NewSQL” class of databases, like MemSQL and VoltDB.

", + "Episodes Title": "Scaling PostgreSQL with Citus Data’s Ozgun Erdogan", + "Episodes Uid": "SED4748410488", + "Episodes Audio File": "0ac3f9e22093b1e4843c17dbf6624202.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "9d", + "Episodes ID": "3705db44-e329-11ea-91a2-c7d5348a2908", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/greg_ripple.mp3", + "Episodes Pubdate Date": "2015-08-13", + "Episodes Summary": "Ripple with Greg Kidd", + "Episodes Title": "Ripple with Greg Kidd", + "Episodes Uid": "SED8337704147", + "Episodes Audio File": "c8168cf2570dd1b35b48459144b71480.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "q6", + "Episodes ID": "3086e394-e329-11ea-91a2-f7b360af047b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/greg_yhat2.mp3", + "Episodes Pubdate Date": "2015-10-05", + "Episodes Summary": "

Yhat is an enterprise software company tackling the challenge of how data science gets done. Their products enable companies and users to easily deploy data science environments and translate analytical models into production code.

Greg Lamp is the Co-founder and CTO of Yhat and previously worked as a product manager in financial services. Yhat was part of the Y Combinator winter 2015 class.

", + "Episodes Title": "Bridging Data Science and Engineering with Greg Lamp", + "Episodes Uid": "SED9683416324", + "Episodes Audio File": "e6042e0c8cbebb9a6998165e6c122237.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "d2", + "Episodes ID": "35f58240-e329-11ea-91a2-2be85233058e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ipfs_juan_benet.mp3", + "Episodes Pubdate Date": "2015-08-25", + "Episodes Summary": "

IPFS enables the creation of completely distributed applications.

Juan Benet is the creator of IPFS and the founder of Protocol Labs.

", + "Episodes Title": "Interplanetary File System (IPFS) with Juan Benet", + "Episodes Uid": "SED1387103311", + "Episodes Audio File": "f8de8003f01bb86a8555ec96f11df3b1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "fu", + "Episodes ID": "34c51df4-e329-11ea-91a2-83369bc2ae6f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/car_hacking.mp3", + "Episodes Pubdate Date": "2015-09-02", + "Episodes Summary": "

Reverse engineers have begun to dissect car security.

Craig Smith is the author of The Car Hacker’s Handbook and the founder of Theia Labs, a research and consulting firm.

", + "Episodes Title": "Car Hacking with Craig Smith", + "Episodes Uid": "SED3870069123", + "Episodes Audio File": "d56a29459e995aa45aff415f4f90a641.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "i9", + "Episodes ID": "33970c12-e329-11ea-91a2-9b501254716b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/caitie_mccaffrey.mp3", + "Episodes Pubdate Date": "2015-09-10", + "Episodes Summary": "

But life can be made easier with tactics such as the actor pattern and the use of conflict-free replicated data types (CRDTs).

Caitie McCaffrey is a distributed systems engineer who currently works at Twitter. She previously worked on Halo 4 at Microsoft and 343 Industries.

At QCon San Francisco, she will be hosting the track Taming Distributed Architecture.

", + "Episodes Title": "Taming Distributed Architecture with Caitie McCaffrey", + "Episodes Uid": "SED7567578188", + "Episodes Audio File": "86ec5bac8360d379e533ebff06d11f10.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5j", + "Episodes ID": "37c5f7c6-e329-11ea-91a2-5397846f4fa4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/rocana_esammer.mp3", + "Episodes Pubdate Date": "2015-08-05", + "Episodes Summary": "

Eric Sammer is the co-founder and CTO of Rocana. At Cloudera, he served as an Engineering Manager responsible for tools and partner integrations. Within that role, he developed many of Cloudera’s best practices for developing large, distributed, data processing infrastructure.

", + "Episodes Title": "Hadoop Ops: Rocana CTO Eric Sammer Interview", + "Episodes Uid": "SED5198896058", + "Episodes Audio File": "1d4e2db734a5ee8279f22534e8e98bc8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 32, + "Episodes ID": "38c757dc-e329-11ea-91a2-4b75b69e0389", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/mongo_bryan_reinero.mp3", + "Episodes Pubdate Date": "2015-07-30", + "Episodes Summary": "

MongoDB is a cross-platform document-oriented database. Bryan Reinero is a developer advocate at MongoDB.

Questions include:

Links:

", + "Episodes Title": "MongoDB with Bryan Reinero", + "Episodes Uid": "SED1693426247", + "Episodes Audio File": "89a393ecfcf042d3b0a243567a6426b5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "be", + "Episodes ID": "3685409c-e329-11ea-91a2-67dc3d68f977", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/influxdb_pauldix.mp3", + "Episodes Pubdate Date": "2015-08-21", + "Episodes Summary": "

Time-series data can be used by for metrics and analytics.

Paul Dix is the CEO of InfluxDB.

", + "Episodes Title": "Time-Series Database with InfluxDB CEO Paul Dix", + "Episodes Uid": "SED1991606237", + "Episodes Audio File": "7f8c1adec044e12350a6c8c507fc9840.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3cy", + "Episodes ID": "f4f6d1ae-e328-11ea-91a2-2f649feca4a4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CloudRD.mp3", + "Episodes Pubdate Date": "2018-01-05", + "Episodes Summary": "

In the first 10 years of cloud computing, a set of technologies emerge that every software enterprise needs; continuous delivery, version control, logging, monitoring, routing, data warehousing. These tools were built into the Cloud Foundry project, a platform for application deployment and management.

As we enter the second decade of cloud computing, another new set of technologies are emerging as useful tools. Serverless functions allow for rapid scalability at a low cost. Kubernetes offers a control plane for containerized infrastructure. Reactive programming models and event sourcing make an application more responsive and simplify the interactions between teams who are sharing data sources.

The job of a cloud provider is to see new patterns in software development and offer tools to developers to help them implement those new patterns. Of course, building these tools is a huge investment. If you’re a cloud provider, your customers are trusting you with the health of their application. The tool that you build has to work properly and you have to help the customers figure out how to leverage the tool and resolve any breakages.

Onsi Fakhouri is the senior VP of R&D for cloud at Pivotal, a company that provides a software and support for Spring, Cloud Foundry and several other tools. I sat down with Onsi to discuss his strategy for determining which products Pivotal chooses to build. There are a multitude of engineering and business elements that Onsi has to consider when allocating resources to a project.

Cloud Foundry is used by giant corporations like banks, telcos and automotive manufacturers. Spring is used by most enterprises that run Java, including most of the startups that I have worked at in the past. Cloud Foundry has to be able to run on premise and in the cloud providers like AWS, Google and Microsoft. Pivotal also has its own cloud, Pivotal Web Services, and all of these stakeholders have different technologies that they would like to see built. Onsi’s job is to determine which ones have the highest net impact and make a decision on those and allocate resources towards them.

I interviewed Onsi at Spring One Platform, which is a conference that is organized by Pivotal who, full disclosure, is a sponsor of Software Engineering Daily. This week’s episodes are all conversations from that conference, and if there’s a conference that you think I should attend and do coverage at, let me know. Whether you like this format or not, I would love to get your feedback. We have some big developments coming for Software Engineering Daily in 2018 and we want to have a closer dialogue with the listeners. Please send me an email, jeff@softwareengineeringdaily.com or join our Slack channel.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cloud R&D with Onsi Fakhouri", + "Episodes Uid": "SED8191339233", + "Episodes Audio File": "ea3325d02f86f1f0299c66af8ef2249b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jb", + "Episodes ID": "0421bf86-e329-11ea-91a2-171cd26bdd12", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/biodeeplearing_edited.mp3", + "Episodes Pubdate Date": "2017-03-20", + "Episodes Summary": "

Biology research is complex. The sample size of a biological data set is often too small to make confident judgments about the biological system being studied.

During Jason Knight’s PhD research, the RNA sequence data that he was studying was not significant enough to make strong conclusions about the gene regulatory networks he was trying to understand.

After working in academia, and then at Human Longevity, Inc Jason came to the conclusion that the best way to work towards biology breakthroughs was to work on the computer systems that enable those breakthroughs. He went to work at Nervana Systems on hardware and software for deep learning. Nervana was subsequently acquired by Intel. In this episode, we discuss how machine learning can be applied to biology today, and how industrial research and development is key to enabling more breakthroughs in the future.

The main lesson I took away from this show is that while we have seen phenomenal breakthroughs in certain areas of health–like image recognition applied to diabetic retinopathy or skin cancer–the challenges of reverse engineering our genome to understand how nucleic acids fit together into humans are still out of reach, and improving the hardware used for deep learning will be necessary to tackle these kinds of informational challenges.

", + "Episodes Title": "Biological Machine Learning with Jason Knight", + "Episodes Uid": "SED4856930579", + "Episodes Audio File": "bdf0617f1792873e0893150c7686a4ae.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3zq", + "Episodes ID": "f2a59ee4-e328-11ea-91a2-0fe68f6b5ebc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_14_RentalHacking.mp3", + "Episodes Pubdate Date": "2018-06-14", + "Episodes Summary": "

If you have ever stayed in a short-term rental (like an Airbnb, HomeAway, or CouchSurfing), you have probably used the wifi network at that rental property. Why wouldn’t you? It’s no different than hopping on an open wifi network at an airport, or a Starbucks, or your friend’s house, right?

One major difference: the hardware is easily accessible to previous guests at the short-term rental. Previous guests could tamper with the software on a router, and use that tampering to do some malicious, surveillant things.

Jeremy Galloway is a security engineer at Atlassian. In today’s show, he explains the risk of using wifi at a short-term rental like an Airbnb–including an explanation of how easy it is to take over a wifi network as a guest at a rental property.

A broader point we discuss: large attack surfaces are difficult to secure. Whether we are talking about Airbnb, or another sharing economy app like Uber, or a large corporate network like Atlassian, or even your own personal life. Jeremy offers some best practices and philosophies for how to respond to the modern world of security.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Hacking Your Short-Term Rental with Jeremy Galloway", + "Episodes Uid": "SED5243418613", + "Episodes Audio File": "734951a21bf634a6ab2f0920f04c063a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3sp", + "Episodes ID": "f2e6bdc0-e328-11ea-91a2-0f7eea74bf9f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_25_Autonomy.mp3", + "Episodes Pubdate Date": "2018-05-25", + "Episodes Summary": "

Self-driving, electric cars will someday outnumber traditional automobiles on the road. As transportation becomes autonomous, it is hard to imagine an industry that will not be affected by the downstream effects of this change.

These cars will likely be managed by fleet operators like Lyft and Uber. We will need fewer cars, and the amount of space dedicated to those cars will shrink dramatically. Parking lots, massive roads, and gas stations will be reclaimed or repurposed. City planning departments will have to devise entirely new strategies.

As the self-driving cars reach consumer availability, an intricate supply chain for these cars will develop. When smartphones became mass-produced, the costs of GPS devices, accelerometers, and other small components dropped steeply. A consequence of the smartphone supply chain was that other devices like consumer drones became affordable. The self-driving car supply chain will lead to the mass production of building blocks for other new devices.

With fewer automotive fatalities, the economics of the car insurance industry might collapse completely. At a minimum, the costs of car insurance will likely shift to the fleet operators, who can purchase that car insurance at prices factoring in their large risk pool.

Frank Chen is a deal and research partner with Andreessen Horowitz. In a series of presentations on the Autonomy Ecosystem, Frank explores the effects of our impending shift to self-driving electric cars. His analysis considers changes to energy infrastructure, the competitive landscape of software companies, and a range of other topics. Frank joins the show to discuss autonomous vehicles and the side effects of widespread autonomous deployments.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Autonomy with Frank Chen", + "Episodes Uid": "SED3307642991", + "Episodes Audio File": "038e1ebdc3a2522d85d24da2075710e1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "39k", + "Episodes ID": "f56f8112-e328-11ea-91a2-b3e755d8ed56", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/NYTGraphql.mp3", + "Episodes Pubdate Date": "2017-11-30", + "Episodes Summary": "

Are we a media company or a technology company? Facebook and the New York Times are both asking themselves this question.

Facebook originally intended to focus only on building technology–to be a neutral arbiter of information. This has turned out to be impossible. The Facebook newsfeed is defined by algorithms that are only as neutral as the input data. Even if we could agree on a neutral data set to build a neutral newsfeed, the algorithms that generate this news feed are not public, so we have no way to vet their neutrality.

Facebook is such a powerful engine for distribution, it has allowed for a rise in the number of publishers who can get their voice heard. As a result, large media companies have lost market share because Facebook has replaced their distribution.

The New York Times has always been a media company–but the standards for media consumption have shot up. Millions of people produce content for free, and that content is distributed through high quality experiences like Twitter, YouTube, Medium, and Facebook. When a page takes too long to load on NewYorkTimes.com, it doesn’t matter how good the content is–the user is going to navigate away before they read anything.

Today, the New York Times has built out an experienced engineering team. In a previous episode, we reported how the Times uses Kafka to make its old content more accessible.  In today’s show, we talk about how the Times uses React and GraphQL to improve the performance and the developer experience of engineers who are building software at the New York Times.

Scott Taylor and James Lawrie are software engineers at the New York Times. In this episode, they explain how the New York Times looks at technology. The user experience on New York Times rivals that of a platform company like Facebook, and this is assisted by technologies originally built at Facebook: React, Relay, and GraphQL.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "React and GraphQL at New York Times", + "Episodes Uid": "SED3927237134", + "Episodes Audio File": "8273077200a0f7e4766f19d1af10d5c1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2f9", + "Episodes ID": "0a641416-e329-11ea-91a2-7f784d1bbbcd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/urbit_edited.mp3", + "Episodes Pubdate Date": "2017-01-20", + "Episodes Summary": "

Urbit is a completely new way of looking at computing. Every user gets a personal server, which runs your apps, wrangles your connected devices, and defines your secure identity. Your urbit presents your whole digital life as a single web service.

Urbit feels foreign and confusing for those of us coming from the traditional web because the normal paradigm is to iterate and paper over the problems of the current platform with new things built on top. Curtis Yarvin, the creator of Urbit, argues that the current model is too fundamentally broken for that to work. As he says: “the Internet as a client-server network has won. The Internet as a peer-to-peer network has failed.”

This sounds like yet another quirky, overambitious developer side project–but Urbit has serious legs. The github repo has had 51 committers over its four years of activity. Last year, a public crowdsale of Urbit address space raised more than $200,000. Peter Thiel was an early investor in the project, perhaps partly due to the combination of persistence, technical skill, and unusual opinions of Curtis Yarvin.

In this episode, Curtis and Galen Wolfe-Pauly join me for a conversation about Urbit–its strange computing platform and the contrarian philosophies that drive its creators.

", + "Episodes Title": "Urbit with Curtis Yarvin and Galen Wolfe-Pauly", + "Episodes Uid": "SED9233493394", + "Episodes Audio File": "2dee36ab8160b213afcf9867e7a818e8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 495, + "Episodes ID": "f214a4e8-e328-11ea-91a2-578d9ad86b2b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_26_GhostwithJohnONolan.mp3", + "Episodes Pubdate Date": "2018-07-26", + "Episodes Summary": "

Blogging is more than 20 years old. Over that period of time, numerous publishing platforms have been created. Squarespace, Blogger, Medium, and Twitter are popular closed source platforms. WordPress has been the most popular open source blogging platform–and much of the Internet (including Software Engineering Daily) runs on WordPress.

WordPress is a powerful platform. News companies, ecommerce websites, and many other kinds of businesses use WordPress as their central publishing tool. But WordPress has been around for 15 years–and there are some potential conflicts of interest between WordPress the open source project and WordPress.com (a company started to host WordPress websites).

John O’Nolan was working as a WordPress developer when he decided to start a new publishing platform called Ghost. Five years later, the Ghost project is a success–with a thriving open source community, a profitable SaaS business, and companies like Digital Ocean and Mozilla using Ghost to host their blogs.

John and I discussed his background with WordPress, what he wanted to do differently with Ghost, and the software architecture of Ghost. We also touched on the Ghost SaaS business and the management of the open source project.

", + "Episodes Title": "Ghost: Open Source Publishing Platform with John O’Nolan", + "Episodes Uid": "SED2135856357", + "Episodes Audio File": "4bac99e4a88c2124e363d9906e7dea9b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2tn", + "Episodes ID": "f8d260b8-e328-11ea-91a2-2f08600c5437", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Episode500.mp3", + "Episodes Pubdate Date": "2017-06-21", + "Episodes Summary": "

Software Engineering Daily has been around for almost two years. In this episode Pranay Mohan and Erika Hokanson join me for a reflection on where we have been and where we are going. Pranay was the producer of Software Engineering Daily for the first year, after which he left and went to work at Snapchat. Erika joined the show 9 months ago to work on operations, ad sales, and expansion plans.

The thesis of Software Engineering Daily has always been that serious, in-depth material about software provides value. Right now we are a podcast about software engineering. We are planning expansion into a larger media company with video, a mobile app, a desktop platform, more podcasts, and more journalism. Pranay, Erika, and I have crafted the vision for Software Engineering Daily.

We want serious, inspiring, technical content to be more widespread. We know that you do too. If you have any suggestions you would like to see from us, you can always email me: jeff@softwareengineeringdaily.com.

It’s already been 500 episodes and I am even more excited about Software Engineering Daily than I was when I began–looking forward to episode 1000.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Episode 500 with Pranay Mohan and Erika Hokanson", + "Episodes Uid": "SED8128773192", + "Episodes Audio File": "17347f39971c521a9da4c4bb55230b23.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2t4", + "Episodes ID": "f909c198-e328-11ea-91a2-17e95b09e2eb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/azureiot_edited.mp3", + "Episodes Pubdate Date": "2017-06-19", + "Episodes Summary": "

A self-driving car needs to be able to quickly respond to changes in driving conditions. A factory needs to be able to quickly respond to changes in workplace safety. For these kinds of applications, we need processing power closer to the user of the application. If we put all of our application logic in the cloud, we will have to make a network round trip for every request.

Servers in the cloud are powerful, but so are the computers at the edge–smartphones, sensors, drones, cars, and on-prem servers. Edge computing is giving us more computation outside the data center.

Olivier Bloch works on Microsoft Azure IoT Edge, a set of services for edge computing. Azure IoT Edge includes on-prem versions of Microsoft Azure technologies. Tools that were previously accessible only in the cloud can be deployed and hosted on premise.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "IoT Edge with Olivier Bloch", + "Episodes Uid": "SED9714389948", + "Episodes Audio File": "8774799b7482120c6f7919fe7c8ad237.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "37j", + "Episodes ID": "f5b27f94-e328-11ea-91a2-df6defba89c6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SemilShah.mp3", + "Episodes Pubdate Date": "2017-11-09", + "Episodes Summary": "

An engineer who wants to start a business using investment capital needs to understand the expectations of investors. The market for the business needs to be huge. The team needs to have a differentiated understanding of the market, or a differentiated product. The CEO needs to have the determination to continue operating the company even when it gets very difficult. And the price needs to be right for the investor.

Even if you are just working at a startup, or considering joining a startup, you must understand how the investment market works. From a raw financial standpoint, it only makes sense to spend your time at a startup that has equity with a high expected value. Your equity will only have high expected value if the company continues to exist long enough to have an exit–the company must either go public or get acquired.

In order to make it down the long and winding road to an exit, a technology company often needs to raise money on multiple occasions. That money is used to pay employees like you! If the company can’t earn enough revenues or raise money, you are going to get fired. Then, you may not have the spare cash to execute your stock options, and you might lose the rights to the equity that you worked so hard for.

The best way to avoid this is to learn to think like an investor–because as an engineer working for equity, you are an investor.

Semil Shah is an early stage seed investor with Haystack, a fund that he started. He also works with GGV Capital, a venture firm investing out of the United States and China. Semil has been blogging about technology for many years, and eventually evolved from a commentator to an investor. In this episode, we explore the dynamics between investors and founders of early-stage technology companies. We also explore the strange market of podcasting. Semil worked at a company called Concept.io, which was acquired by Apple for $30M.

We have done some great shows with other engineering investors like Chris Dixon and Adrian Colyer. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Early Investments with Semil Shah", + "Episodes Uid": "SED8791984829", + "Episodes Audio File": "02754c70a8ad0ee088be20ea95ee1f8a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3nk", + "Episodes ID": "f38e65de-e328-11ea-91a2-5bd945701445", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_11_GowithErikStMartin.mp3", + "Episodes Pubdate Date": "2018-04-11", + "Episodes Summary": "

Go is a language designed to improve systems programming. Go includes abstractions that simplify aspects of low level engineering that are historically difficult—concurrency, resource allocation, and dependency management. In that light, it makes sense that the Kubernetes container orchestration system was written in Go.

Erik St. Martin is a cloud developer advocate at Microsoft, where he focuses on Go and Kubernetes. He also hosts the podcast “Go Time,” and has written a book on Go called Go In Action.

Recently, Erik helped build the virtual Kubelet project, which allows Kubernetes nodes to be backed by services outside of that cluster. If you want your Kubernetes cluster to leverage abstractions such as serverless functions and standalone container instances, you can use Virtual Kubelet to treat these other abstractions as nodes.

Erik also discussed his experience using Kubernetes at Comcast—which was a great case study. Near the end of the show, he also talked about organizing Gophercon, a popular conference for Go programmers—if you are organizing a conference or thinking about organizing one, it will be useful information to you. Full disclosure: Microsoft, where Erik works, is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Go Systems with Erik St. Martin", + "Episodes Uid": "SED1966694198", + "Episodes Audio File": "79d7926bdb1c37ef1ff6f4f1a63b31a3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ql", + "Episodes ID": "ee044372-e328-11ea-91a2-5b9c12b4123d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_20_EmergingMarketKenya.mp3", + "Episodes Pubdate Date": "2019-05-20", + "Episodes Summary": "

Africa is rapidly adopting the same software and hardware technologies that have transformed the western world over the last few decades. But access to computers and technology education is still uneven. Where there is access to computers, smartphone adoption often comes before access to laptops or desktop computers.

Nelly Cheboi is the founder of TechLit Africa, an organization that works to connect schools and families in Africa with computers and software. Nelly studied computer science, and worked as a software engineer before leaving her career to focus full-time on building a scalable model to take refurbished computers and give them to Africans who can make good use of them.

TechLit Africa is also building a software stack to equip schools in Africa without an Internet connection with an internal subnet including Wikipedia and other educational resources, so that people in the school can get an Internet-like experience despite a lack of access to the full Internet.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "EmergingMarkets: Kenya with Nelly Cheboi", + "Episodes Uid": "SED9830956293", + "Episodes Audio File": "c69760eb2cc58ab3038729ea3dfc949f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5c1", + "Episodes ID": "ef60f8c8-e328-11ea-91a2-e33b9cc55a59", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_14_KubernetesSecurity.mp3", + "Episodes Pubdate Date": "2019-02-14", + "Episodes Summary": "

A Kubernetes cluster presents multiple potential attack surfaces: the cluster itself, a node running on the cluster, a pod running in the node, a container running in a pod. If you are managing your own Kubernetes cluster, you need to be aware of the security settings on your etcd, your API server, and your container build pipeline.

Many of the security risks of a Kubernetes cluster can be avoided by using the default settings of Kubernetes, or by using a managed Kubernetes service from a cloud provider or an infrastructure company. But it is useful to know about the fundamentals of operating a secure cluster, so that you can hopefully avoid falling victim to the most common vulnerabilities.

Liz Rice wrote the book Kubernetes Security with co-author Michael Hausenblas. Liz works at Aqua Security, a company that develops security tools for containerized applications. In today’s show, Liz gives an overview of the security risks of a Kubernetes cluster, and provides some best practices including secret management, penetration testing, and container lifecycle management.

", + "Episodes Title": "Kubernetes Security with Liz Rice", + "Episodes Uid": "SED2561058967", + "Episodes Audio File": "a04c90e00b710cc5ea6e769b4d683a8d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4wo", + "Episodes ID": "f09767cc-e328-11ea-91a2-a347cc31f90b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_12_PolicyEngines.mp3", + "Episodes Pubdate Date": "2018-11-12", + "Episodes Summary": "

Policies define which users and applications can access and modify resources in a computer system.

In a file system, a user might have permission to read or write to a file. In a cloud infrastructure deployment, a user might have the rights to deploy a new server. One microservice may or may not have the necessary permissions to talk to another microservice. All of these are use cases where a “policy” defines the behavior within a computer system.

Policies in a company can be managed in a range of ways: configuration files, dashboards, and centralized permissions databases. A policy engine is a system for managing and automating the policy creation and deployment within an organization.

Microservices need to verify each request that comes in to ensure that the request has the correct permissions. To check those permissions, a microservice can contact the policy engine. The policy engine has all the information from the whole organization about who is allowed to do what. However, talking to the policy engine over the network can be a slow process.

Open Policy Agent is a deployable agent that can run as a sidecar next to a service, and check policies by looking inside of a cache. Torin Sandall is a core committer to the Open Policy Agent project, and he joins the show to talk about policy management, the Open Policy Agent, and the Kubernetes ecosystem (and surprisingly, WebAssembly).

", + "Episodes Title": "Open Policy Agent with Torin Sandall", + "Episodes Uid": "SED1529856575", + "Episodes Audio File": "50f1c6fe4bd7e630b54f5568771c9a6f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3kv", + "Episodes ID": "f3f73974-e328-11ea-91a2-f391e841bdb3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_13_Metamask.mp3", + "Episodes Pubdate Date": "2018-03-13", + "Episodes Summary": "

Decentralized applications can be built on the Ethereum blockchain. Just as the Bitcoin blockchain is a distributed, append-only ledger of financial transaction history, Ethereum is a distributed, append-only ledger of computational transaction history.

New kinds of applications can be built on the Ethereum blockchain—and just like every new technology, we need an interface to bridge that new technology and our existing technology.  We can use a pure Ethereum browser like Mist—or we can use a Chrome extension like Metamask to turn our normal browser into an Ethereum interface.

Dan Finlay is the lead developer of Metamask. In today’s episode, we explore why you would want to interface with decentralized applications, and the different ways of doing so. A few examples we explore—simple transactions like transferring Ether from one person to another; or transacting with a smart contract.

My personal anecdote: I recently used Metamask for the first time to fund a GitCoin issue. GitCoin is a way to put up financial rewards for people solving open source issues. I locked up $42 in an Ethereum smart contract, and it became the bounty of that issue. The issue was solved, and I released the $42 from the smart contract to be sent to the developer who solved it. In this example, Ethereum served as a simple escrow service. To send my Ether, I used the Metamask plugin on my Chrome browser. If you are a little confused—don’t worry. We explain it all in this episode.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Metamask with Dan Finlay", + "Episodes Uid": "SED8335575480", + "Episodes Audio File": "e10c5130c255e8eaf696c4db03fcf233.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3m5", + "Episodes ID": "f3c4778c-e328-11ea-91a2-db0d62ef7f5b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_27_Falcon.mp3", + "Episodes Pubdate Date": "2018-03-27", + "Episodes Summary": "

Soumya Basu is a PhD student at Cornell, where he studies distributed systems problems associated with cryptocurrencies. Soumya is advised by Emin Gun Sirer, a Cornell professor who previously appeared on the show to discuss smart contract security.

Soumya joins the show today to talk about a variety of issues in the cryptocurrency space. We first explored the degree to which Bitcoin and Ethereum are actually decentralized–which might be less than you think. Because of the centralization of mining pools, much of the transaction processing is also centralized. After talking about decentralization, we got into Soumya’s research focus–cryptocurrency networking and block propagation.

Bitcoin transactions are collected into blocks. When a Bitcoin full node solves the cryptographic puzzle associated with a block of transactions, that full node broadcasts the new block to all the other nodes in the network. It is important for that block broadcast to be fast and efficient, so that the other full nodes in the network can be made aware of the new block as soon as possible, and they can start working from the updated chain.

The problem of making all nodes in the network aware of a new block is known as “block propagation.” Block propagation can be accelerated through the use of relay nodes. A relay node is a node that is dedicated to communicating these new blocks throughout the blockchain. Soumya is working on a relay node architecture called Falcon–and in this episode we talk all about what Falcon is.

If you are looking for all 700 episodes of Software Engineering Daily, check out our apps on the iOS or Android app store. We’ve got tons of episodes on blockchains, business, distributed systems, and tons of other topics. If you want to become a paid subscriber to Software Engineering Daily, you can hear all of our episodes without ads–you can subscribe at softwaredaily.com. And all of the code for our apps is open source. If you are looking for an open source community to be a part of, come check out github.com/softwareengineeringdaily.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cryptocurrency Networking with Soumya Basu", + "Episodes Uid": "SED9450986287", + "Episodes Audio File": "f51020d225b740af933083f18269b49c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2rc", + "Episodes ID": "fa8790b8-e328-11ea-91a2-af9612cc807a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/iosandlibsyn_edited.mp3", + "Episodes Pubdate Date": "2017-05-30", + "Episodes Summary": "

Apple controls the iOS ecosystem. As an accident of history, Apple also controls the podcasting ecosystem. Unlike most ecosystems within Apple’s dominion, podcasts remain open. A podcaster merely has to record an mp3, distribute it via RSS feed, and submit that RSS feed to the iTunes podcast portal.

Podcasting has thrived in recent years, but very few technology companies have managed to take advantage of that growth. Libsyn is the most popular place to host a podcast. Libsyn is a combination of a CDN, a hosting service, analytics, and place to get an RSS feed for a podcaster. There have been many clones of Libsyn over the years, but the company remains the industry standard.

For people who are confused–iTunes does not host any audio files. It is just an index of feeds. A podcaster needs to host audio files somewhere in order to give iTunes access.

Today’s guest Rob Walch joins the show to talk about podcasts–including his podcast Today in iOS. I had a great time meeting Rob at the Microsoft Build conference. Special thanks to Bharat Bhat for organizing the podcast booths at Microsoft Build.

", + "Episodes Title": "iOS and Podcasts with Rob Walch", + "Episodes Uid": "SED3139472305", + "Episodes Audio File": "d3467f08688c7148c11d505a0d9a807a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "63d", + "Episodes ID": "ecab7a86-e328-11ea-91a2-8772ba42bc06", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_22_TechnicalOnboarding.mp3", + "Episodes Pubdate Date": "2019-08-22", + "Episodes Summary": "

When a new employee joins a software company, it is often unclear where that employee should begin. Do they have a mentor? What are they working on? What are the expectations for how fast that employee should be contributing?

The early period of employment is often referred to as “onboarding.” During the onboarding period, an employee will learn the basics of the company they have just joined. These basics include the work procedures, meeting schedules, expectations, and technical tools that an employee needs to become productive.

A poor onboarding process can slow an employee down, and even cause them to quit the company entirely. Conversely, a good onboarding process can accelerate an employee towards rapid contribution within the organization. A scalable onboarding process can be a difference in millions of dollars in productivity per year across the organization.

Kristen Gallagher is the founder of Edify, a company that helps organizations define and implement their onboarding process. Kristen joins the show to talk about the ingredients of a successful onboarding process and what she is doing with her company Edify.

", + "Episodes Title": "Technical Onboarding with Kristen Gallagher", + "Episodes Uid": "SED5702115526", + "Episodes Audio File": "8ee6cdb50c087cb2561bd80d5f32e3f6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2gh", + "Episodes ID": "0811fd9a-e329-11ea-91a2-5bc8224610e7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/managementwithmike_edited.mp3", + "Episodes Pubdate Date": "2017-02-08", + "Episodes Summary": "

Engineering managers face a different set of problems than engineers themselves. Whether they are hiring new employees, firing underperformers, or guiding a team of existing engineers, engineering management is all about people. Empathy is paramount because management is like being a professional therapist for the members of your team.

Mike Borozdin has been managing engineers for more than a decade and blogs about engineering management. In this episode, we cover the core responsibilities of an engineering manager and some strategies around how to do it right.

This episode is useful for anyone looking to improve their relationship with their manager, move into management, or improve as a manager.

", + "Episodes Title": "Engineering Management with Mike Borozdin", + "Episodes Uid": "SED6566413748", + "Episodes Audio File": "1e404c74e3a903ac6829391a7afc4045.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5u3", + "Episodes ID": "eda70dd8-e328-11ea-91a2-f3458bf67764", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_17_Render.mp3", + "Episodes Pubdate Date": "2019-06-17", + "Episodes Summary": "

Cloud computing was popularized in 2006 with the launch of Amazon Web Services. AWS allowed developers to use remote server infrastructure with a simple set of APIs. But even with AWS, it was still not simple to deploy and manage a web application.

In 2007, Heroku launched a platform built on top of AWS. Heroku focused on the developer experience by optimizing for users who were deploying Ruby on Rails applications. Since then, Heroku has expanded into other forms of managed infrastructure, including other application frameworks like NodeJS, and databases like Postgres.

Heroku was the first popular “layer 2” cloud provider. Twelve years later, it is probably still the most popular. But there have been many other cloud providers built on top of AWS, including Netlify, Zeit, Spotinst, and Firebase.

Layer 1 cloud providers are Google Cloud, AWS, Azure, Digital Ocean, and other raw infrastructure providers. These companies provide a great service in their low cost, commodity infrastructure. But the layer 1 providers are not optimizing for developer experience. They need to cater to a broad set of developers, some of whom want to work at a low level.

A layer 2 cloud provider can build an opinionated solution that serves a subset of the overall cloud market particularly well.

Render is a layer 2 cloud provider that optimizes for specific developer workflows, such as deploying a NodeJS web server, a static site, or a Docker container. Anurag Goel is the founder of Render, and he joins the show to discuss the strategy and the economics of Render. Anurag was also one of the early employees at Stripe, and he discusses his experience and learnings from working at the company.

", + "Episodes Title": "Render: High Level Cloud with Anurag Goel", + "Episodes Uid": "SED8081680456", + "Episodes Audio File": "6ef488d08b50b35b23066c62ed61095a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2gf", + "Episodes ID": "084b7a34-e329-11ea-91a2-17d7dc3a2736", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2opensource_edited.mp3", + "Episodes Pubdate Date": "2017-02-07", + "Episodes Summary": "

Open source software is publicly available code that is worked on in the open by large crowds of developers. Almost all new software today uses some open source software in its code. But most people never contribute to open source themselves. Some people would love to get involved in open source, but they don’t know how to get started.

Shubheksha Jalan found herself in this position. In her early attempts to break into open source, she failed to get much traction and found the open source community hostile to newcomers. She would fix beginner issues, but had trouble figuring out how to make more complex contributions. Eventually she found success and wrote about it. In this episode she takes us through that journey.

If you are wondering how to get into open source, this episode is for you.

", + "Episodes Title": "Open Source Contribution with Shubheksha Jalan", + "Episodes Uid": "SED4803083760", + "Episodes Audio File": "f4c4ce5e988880646ddc6b84724ff44a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "31m", + "Episodes ID": "f68f42f8-e328-11ea-91a2-67e9d4da870e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/AttackAttribution.mp3", + "Episodes Pubdate Date": "2017-09-07", + "Episodes Summary": "

When a cyber attack occurs, how do we identify who committed it? There is no straightforward answer to that question.

Even if we know Chinese hackers have infiltrated our power grid with logic bombs, we might not be able to say with certainty whether those hackers were state actors or rogue Chinese hackers looking for an offensive asset to sell to their government.

Even if we know someone in Russia launched an attack on the banking system in Ukraine, we might not know whether that attack came from the government or from aggressive non-governmental forces.

Accurate cyberattack attribution is key to preventing diplomatic mistakes in the modern battleground of the Internet.

Today’s guest John Davis is one of the authors of the report called “Stateless Attribution: Toward International Accountability in Cyberspace”.

John is a senior information scientist with RAND Corporation, a non-profit institution that helps improve policy and decisionmaking through research and analysis. This report was commissioned by Microsoft, and it provides a deep assessment of our current ability to attribute a cyberattack to the perpetrator of that attack.

If you like this episode, we have done many other shows about security, with guests like Bruce Schneier and Samy Kamkar. You can check out our back catalog by downloading the Software Engineering Daily app for iOS, where you can listen to all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that.

", + "Episodes Title": "Attack Attribution with John Davis", + "Episodes Uid": "SED5695004380", + "Episodes Audio File": "db9c8f63731528bd851d0f6852d9b35b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "63a", + "Episodes ID": "ecb979c4-e328-11ea-91a2-5fd8e04d2b7c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_19_OpenSourceBusinesswithKarthikandOthers.mp3", + "Episodes Pubdate Date": "2019-08-19", + "Episodes Summary": "

Open source software has evolved into a thriving, multifaceted ecosystem.

Open source encompasses operating systems and databases. Open source embodies both altruism and self-interest. And open source enables thriving businesses from WordPress blogs to hundred billion dollar cloud providers.

There is a large set of business models that can be built around a successful open source project. Some of these business models are more defensible than others. A company based around open source must make a deliberate set of tradeoffs around how their private company will relate to the public open source ecosystem.

Today’s episode is a discussion of open source business models with Karthik Ranganathan, Heather Meeker, and Matt Asay. Karthik is the CTO of YugaByte, an open source distributed SQL database. Heather Meeker is an open source licensing specialist and a founding partner of OSS Capital. Matt Asay is a longtime executive who has worked in several open source based companies including MongoDB–he has also written at length about open source. Full disclosure: YugaByte, where Karthik works, is a sponsor of SE Daily.

", + "Episodes Title": "Open Source Business Models with Karthik Ranganathan, Heather Meeker, and Matt Asay", + "Episodes Uid": "SED7123559342", + "Episodes Audio File": "bce102d688af159aeab829fc39080298.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ar", + "Episodes ID": "f548b596-e328-11ea-91a2-e38cfaad48c0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ScalableMultiplayerGames.mp3", + "Episodes Pubdate Date": "2017-12-11", + "Episodes Summary": "

Remember when the best game you could play on your phone was Snake?

In 1998, Snake was preloaded on Nokia phones, and it was massively popular. That same year Half-Life won game of the year on PC. Metal Gear Solid came out for Playstation. The first version of Starcraft also came out in 1998.

In 1998, few people would have anticipated that games with as much interactivity as Starcraft would be played on mobile phones twenty years later. Today, mobile phones have the graphics and processing power of a desktop gaming PC from two decades ago.

But one thing still separates desktop gaming from mobile gaming: the network.

With desktop gaming, users have a reliable wired connection that keeps their packets moving over the network with speeds that let them compete with other users. With mobile gaming, the network can be flaky. How do we architect real-time strategy games that can be played over an intermittent network connection?

Yan Cui is an engineer at Space Ape Games, a company that makes interactive multiplayer games for mobile devices. In a previous episode, Yan described his work re-architecting a social networking startup where the costs had gotten out of control.  Yan has a skill for describing software architecture and explaining the tradeoffs.

When architecting a multiplayer mobile game, there are many tradeoffs to consider. What do you build and what do you buy? Do you centralize your geographical deployment to make it easier to reconcile conflicts, or do you spread your server deployment out globally? What is the interaction between the mobile clients and the server?

The question of interaction between client and server for a mobile game has lessons that are important for anyone building a highly interactive mobile application.

For example, think about Uber. When I make a request for a car, I can look at my phone and see the car on the map, slowly approaching me. The driver can look at his phone and see if I move across the street.

This is accomplished by synchronizing the data from the driver’s phone and my phone in a centralized server, and sending the synchronized state of the world out to me and the driver. How much data does the centralized server need to get from the mobile phones? How often does it need to make those requests?

The answers to these questions will vary based on bandwidth, device type, phone battery life, and other factors.

There are similar problems in mobile game engineering, when users are in different players on a virtual map. They are fighting each other, trying to avoid enemies, trying to steal power ups from each other. Mobile games can be even more interactive than a ridesharing app like Uber, so the questions of data synchronization can be even harder to answer.

On Software Engineering Daily, we have explored the topic of real-time synchronization in our past shows about the infrastructure of Uber and Lyft. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Yan Cui’s new video course: AWS Lambda in Motion

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Scalable Multiplayer Games with Yan Cui", + "Episodes Uid": "SED6147651645", + "Episodes Audio File": "bb60f49a1b55cfc5683708f0f922aa1a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "65d", + "Episodes ID": "ec7f4b8c-e328-11ea-91a2-c3168bf1a886", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_06_Replit.mp3", + "Episodes Pubdate Date": "2019-09-06", + "Episodes Summary": "

The browser has become the central application of the consumer operating system. Every piece of client software, from email to document management, has become usable through the browser. Even modern desktop software such as Slack is built using Electron, a tool for building client applications that essentially run inside of a browser without an address bar.

One activity that still takes place largely outside of the browser is the process of writing and deploying code. A developer often uses an IDE such as Eclipse to write their code, then switches over to a terminal where they can build and deploy their code to a remote server running in the cloud.

For a developer who has been writing code for a long time, this process feels completely intuitive. But for a new developer, it can be totally disorienting. New developers sometimes have trouble understanding the difference between a local and remote environment, or how to use repository management software like Git. This is in addition to all the other problems a new developer might be dealing with, such as language installation, syntax, and package management.

Repl.it is a browser-based coding environment, compute engine, and collaborative workspace. Repl.it has found significant traction among new programmers who begin their programming journey within Repl.it and then stay in the environment, even as their applications become more richly featured and complicated.

Repl.it is an amazing piece of software, and the story behind it is remarkable. Amjad Masad had the idea for Repl.it many years before he started the company for it, but he needed to first build up the money and confidence in order to go after the business with full force. Amjad joins the show to talk about his long journey towards building Repl.it, and to discuss the thriving Repl.it platform in its current form.

", + "Episodes Title": "Repl.it: Browser Coding with Amjad Masad", + "Episodes Uid": "SED4118291619", + "Episodes Audio File": "618fdfaa6acb7c5de034c4eb7dfaa4b2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4q1", + "Episodes ID": "f0f9372c-e328-11ea-91a2-978343de3e11", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_15_SnowflakeData.mp3", + "Episodes Pubdate Date": "2018-10-15", + "Episodes Summary": "

A data warehouse provides fast access to large data sets for analytics, data science, and dashboards. A data warehouse differs from a transactional database, because you often do not need to update specific records. Because of the read-only nature of the access patterns, and the high volumes of data being queried, the design of a data warehouse is very different than a transactional database.

With a transactional database (such as MySQL or MongoDB), it is important to have consistency guarantees. For example, consider a transactional database that serves as the backend for banking applications. If multiple frontend servers are hitting that transactional database to withdraw money, you need the records to be quickly updated. You need to avoid race conditions, so that two servers cannot withdraw the entire bank account balance simultaneously from different locations.

In contrast to transactional databases, a data warehouse is often used to process a query that encompasses a big data set. For example, Netflix might want to answer the question: “how many users that watched House of Cards also watched Black Mirror?” Netflix has a lot of users, so they will want to be accessing those user records in a way that lets them scan through the records quickly.

Christian Kleinerman is the VP of product at Snowflake Computing. Snowflake’s main product is a cloud data warehouse. In today’s show, we talk about the difference between a data warehouse, a data lake, and a transactional database, and the process of moving data sets between them, often known as ETL.

This show continues our series on data engineering and data platforms. As companies accumulate more and more data, the complexity of managing that data and taking full advantage of it is escalating. Christian gives his perspective on these changing trends, and describes the plans for Snowflake to evolve as a business.

", + "Episodes Title": "Data Warehouse with Christian Kleinerman", + "Episodes Uid": "SED7474375004", + "Episodes Audio File": "803cb52f2d206b8b429a41dd09a1da1d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "tr", + "Episodes ID": "2f35dc66-e329-11ea-91a2-cb9ac3502115", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/gavin_wood_edited3.mp3", + "Episodes Pubdate Date": "2015-10-19", + "Episodes Summary": "

Ethereum is a decentralized platform for applications that are guaranteed to run exactly as expected via smart contracts.

Gavin Wood is a Co-founder and the Director of Development at Ethereum.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

", + "Episodes Title": "Ethereum with Gavin Wood", + "Episodes Uid": "SED6031917991", + "Episodes Audio File": "d097dc87e09fe8bb781c962c1244cc0d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2v1", + "Episodes ID": "f75f2f18-e328-11ea-91a2-db0ffd6b69d0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/KafkaCloud.mp3", + "Episodes Pubdate Date": "2017-07-10", + "Episodes Summary": "

Apache Kafka is an open-source distributed streaming platform. Kafka was originally developed at LinkedIn, and the creators of the project eventually left LinkedIn and started Confluent, a company that is building a streaming platform based on Kafka.

Kafka is very popular, but is not easy to deploy and operationalize. That is why Confluent has built a Kafka-as-a-service product, so that managing Kafka is not the job of an on-call DevOps engineer.

Neha Narkhede is the CTO of Confluent and she has been on the show twice before to discuss Kafka. In our last episode, we discussed event sourcing and CQRS with Kafka. In this episode, we explore more common enterprise uses for Kafka, and Neha talks about the engineering complexities of building a managed Kafka-as-a-service product.

", + "Episodes Title": "Kafka in the Cloud with Neha Narkhede", + "Episodes Uid": "SED3047230706", + "Episodes Audio File": "24d7c28a6bc00c8d09dd2f55c01c8117.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 370, + "Episodes ID": "f5c0cf54-e328-11ea-91a2-5b6d0eb425fb", + "Episodes Original URL": "http://media.blubrry.com/audio_reviews/p/traffic.libsyn.com/sedaily/Webtask.mp3", + "Episodes Pubdate Date": "2017-11-06", + "Episodes Summary": "

Serverless architecture is software that runs without an addressable server. Serverless is made possible by two types of technology: platform as a service providers like Auth0, and functions as a service like AWS Lambda.

With both of these technologies, we can program logic that runs without being deployed to a server.

Functions as a service are cheap and scalable. Write your code for a Serverless function, and the cloud provider will cheaply deploy and execute that function on some server somewhere. The difficult part is maintaining state.

Since Serverless compute instances are ephemeral, you aren’t dealing with a system that will keep track of your state—it is going to disappear eventually.

The ephemeral nature of Serverless code requires us to shift our thinking—but the dramatic cost and simplified scalability make it well worth the effort.

Serverless functions can add complexity in exchange for lower price. Serverless “platform as a service” often lowers complexity at a slightly higher price.

A Serverless database like Firebase handles database scaling and gives you a nice web interface. A Serverless machine learning platform like Google CloudML gives your models scalability and controlled deployment. A Serverless authentication service like Auth0 manages your authentication.

In addition to authentication, Auth0 has built a set of tools to allow SaaS companies to extend their platforms into a sandboxed code execution environment. Bobby Johnson is an engineer at Auth0, and he joins the show to describe the toolbox that Auth0 has developed: authentication, webtasks, and extensibility–and how the world of “serverless” architecture is evolving. Full disclosure, Auth0 is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless Authentication with Bobby Johnson", + "Episodes Uid": "SED6164707202", + "Episodes Audio File": "79f62bd0ec92a2eadb52c87bfb590ecb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ks", + "Episodes ID": "ee9ddf8c-e328-11ea-91a2-735342e58cd6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_09_StreamingwithHoldenKarau.mp3", + "Episodes Pubdate Date": "2019-04-09", + "Episodes Summary": "

RECENT UPDATES:

FindCollabs $5000 Hackathon Ends Saturday April 15th, 2019

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

Distributed stream processing allows developers to build applications on top of large sets of data that are being rapidly created. Stream processing is often described as an alternative to batch processing. In batch processing, a single large computation is performed over a large, static data set. In stream processing, a computation is performed repeatedly and continuously over a data set that is being appended to.

A stream is often stored in a distributed queue such as Kafka, Kinesis, Pulsar, or Google PubSub. A stream is often processed with a stream processing tool such as Spark, Flink, Storm, or Google Cloud Dataflow.

Holden Karau is an engineer who works on open source projects at Google. She returns to the show to describe the state of stream processing and discuss modern best practices.

", + "Episodes Title": "Streaming with Holden Karau", + "Episodes Uid": "SED5419795828", + "Episodes Audio File": "55ee137b3b37635c4cc63113640138c0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ms", + "Episodes ID": "fdf0c8b4-e328-11ea-91a2-1b9a62c9f7f3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RobotAssistant.mp3", + "Episodes Pubdate Date": "2017-04-28", + "Episodes Summary": "

We view our iPhones as inanimate objects. But when we see robots such as the Boston Dynamics machines that move with a motion that seems like an animal, the robot comes alive. We feel more sympathy and connection towards it.

Today’s episode is about the distinction between inanimate machines and machines that seem alive.

Peeqo is a robot assistant similar to Amazon Echo or Google Home. It was built by Abhishek Singh as part of his thesis. Abhishek wanted to explore the border between inanimate electronics and the electronics we personify. Peeqo is a cylindrical tube that bends slightly, like the human neck. At its head, it has a smartphone-sized screen that displays gifs to reflect its feedback visually.

Abhishek also has a company called Svrround, which makes 360 degree video experiences. We explore the changes to engineering that allow someone to be involved in two cutting-edge projects at once despite having very few employees working with him.

This was an energizing conversation, and I greatly enjoyed meeting Abhishek. I hope to have him on again in the future.

We would love to get your feedback on Software Engineering Daily. Please fill out the listener survey, available on softwareengineeringdaily.com/survey. Also–Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

", + "Episodes Title": "Robot Assistant with Abhishek Singh", + "Episodes Uid": "SED5569623181", + "Episodes Audio File": "0471933277aa188f36acebd79b8b232d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ij", + "Episodes ID": "f4413fce-e328-11ea-91a2-a36f46b7292d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_20_GwenShapiro.mp3", + "Episodes Pubdate Date": "2018-02-20", + "Episodes Summary": "

Kafka is at the center of modern streaming systems. Kafka serves as a database, a pubsub system, a buffer, and a data recovery tool. It’s an extremely flexible tool, and that flexibility has led to its use as a platform for a wide variety of data intensive applications.

Today’s guest is Gwen Shapira, a product manager at Confluent. Confluent is a company that was started by the creators of Apache Kafka–Jay Kreps, Neha Narkhede, and Jun Rao, who have all been on the show in previous episodes. In those shows, we discussed the inner workings of Kafka. This episode is more about practical use cases and design patterns.

Gwen explores a few use cases. First, reconciling data between different servers. A massive, international, multi-user game like World of Warcraft needs to keep its users in sync despite the fact that those users are pinging different server locations. Kafka can help reconcile data between the multiple servers. This discussion reminded me of the awesome show we did with Yan Cui about scalable multiplayer games.

Other examples we discussed include log management, data enrichment, and large scale analytics. It was a great conversation and I think you will enjoy it as well.

Summer internship applications to Software Engineering Daily are also being accepted. If you are interested in working with us on the Software Engineering Daily open source project full-time this Summer, send an application to internships@softwareengineeringdaily.com. We’d love to hear from you.

If you haven’t seen what we are building, check out softwaredaily.com, or download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kafka Design Patterns with Gwen Shapira", + "Episodes Uid": "SED5860983788", + "Episodes Audio File": "f7d83e1bcb9c060509d278a6983a27fc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yz", + "Episodes ID": "f6d8d364-e328-11ea-91a2-ffef6bb3aa66", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/JuanBuritica.mp3", + "Episodes Pubdate Date": "2017-08-16", + "Episodes Summary": "

Building and nurturing a developer community is hard work but it is vital for the growth of a country’s technology ecosystem. When communities coalesce around programming languages, tools or programming methods, what follows is a network of conferences, meet ups and other similar events.

Juan Pablo Buriticá, VP of Engineering at Splice, has spent the last decade building developer communities in his home country of Colombia and across Latin America as well as running distributed engineering teams. He has helped to launch a number of conferences, meet-ups and more recently, an online meet-up providing advanced technical information for native Spanish speakers.

In today’s episode, Juan returns to Software Engineering Daily to speak with Carl Mungazi about the benefits of having a distributed engineering team and hiring developers from developing nations. He discusses how Colombia came to have the largest Spanish-speaking JavaScript community in the world and the importance of good communication when building software with a team of developers based around the world.

", + "Episodes Title": "Building Developer Communities with Juan Pablo Buriticá", + "Episodes Uid": "SED8063197590", + "Episodes Audio File": "f3d1605f8d522d00250a114c689e080e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yf", + "Episodes ID": "f6f0f9f8-e328-11ea-91a2-27243f95bc43", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/StateofJavascript.mp3", + "Episodes Pubdate Date": "2017-08-09", + "Episodes Summary": "

JavaScript is moving so fast. It’s not easy to keep up with all of the frameworks, build tools, and packages. No other language spans frontend to backend, mobile to web to server.

Sacha Greif is an independent designer and developer most prominent in his roles as co-author of Discover Meteor and community builder at Sidebar.io, a design newsletter with over 35,000 subscribers, and Hacker News Kansai. He is currently best known in the Javascript community as the maintainer of VulcanJS, and for his annual State of Javascript survey which is now open for 2017.

In this episode, Shawn Wang guests hosts a discussion about both projects and Sacha’s thoughts on independent web design and development.

", + "Episodes Title": "State of JavaScript with Sacha Greif", + "Episodes Uid": "SED5180317720", + "Episodes Audio File": "d2cd0281bf3667e63e1a2445f47e036e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48s", + "Episodes ID": "f1c604b4-e328-11ea-91a2-ab932941f223", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_09_KlarnaEngineering.mp3", + "Episodes Pubdate Date": "2018-08-10", + "Episodes Summary": "

Klarna is a payments company headquartered in Sweden. Since being established in 2005 it has grown to handling $21 billion in online sales in 2017. Roughly 40% of all e-commerce sales in Sweden go through Klarna.

Klarna’s original differentiator was that it allowed users to checkout of e-commerce stores without entering in credit card information. Instead, the user enters an email address and registers with Klarna. This allows Klarna to assume the risk of the transaction, in place of the credit card company.

Klarna’s clever payment method became very popular, and 13 years later Klarna is a bank with a variety of financial services and payment methods. Marcus Granstrom is a director of engineering at Klarna. His work ranges from product development to systems architecture to management. His cross functional role has some similarity to Raylene Yung from Stripe, who is also an engineering director at a payments company, and was on the show yesterday.

Marcus walked me through the life of a payment hitting Klarna’s servers, and this served as a nice starting point for a conversation about Klarna’s infrastructure, their product, and their engineering practices.

", + "Episodes Title": "Klarna Engineering with Marcus Granström", + "Episodes Uid": "SED1911832088", + "Episodes Audio File": "5cf186a6cc385d0f484906add6d30dfa.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 505, + "Episodes ID": "f0523238-e328-11ea-91a2-df94126b459f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_28_OnPremCloud.mp3", + "Episodes Pubdate Date": "2018-12-03", + "Episodes Summary": "

Not every company wants to move to the public cloud.

Some companies have already built data centers, and can continue to operate their business with their own servers. Some companies have compliance issues with the public cloud, and want to operate their own servers to avoid legal risk.

Operating a data center is not easy. Operating systems need to be updated and security vulnerabilities need to be patched. Servers fail, and their workloads need to be automatically scheduled onto other servers to avoid downtime.

In contrast to classic on-prem data center management, the cloud provides many benefits: automatic updates, an infinite pool of resources, fully programmable infrastructure as code. In the cloud, developers can provision infrastructure with an API request. Continuous delivery pipelines can be spun up at the click of a button.

This tooling makes it dramatically easier for developers to move quickly, and for a business to move faster. Companies that operate their own data center want to be able to have these benefits of the cloud while still controlling their own infrastructure.

Today’s guest Bob Fraser works at HPE on OneView, a tool for managing on-prem infrastructure like a cloud. Bob describes the difficulties of managing legacy on-prem infrastructure, and the advantage of building a management layer on top of data center infrastructure to make it more programmable.

We’ve done lots of shows recently about Kubernetes in the context of cloud computing. Today’s show outlines how modern on-prem infrastructure can be managed like a cloud. Full disclosure: HPE is a sponsor of Software Engineering Daily.

", + "Episodes Title": "On-Prem Cloud with Bob Fraser", + "Episodes Uid": "SED8450995405", + "Episodes Audio File": "a6ce23498d4a95a0fcc24a2716df490e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3zo", + "Episodes ID": "f2af27a2-e328-11ea-91a2-837120108ec3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_12_Necto.mp3", + "Episodes Pubdate Date": "2018-06-12", + "Episodes Summary": "

In the tech industry, we have all grown to fear “lock-in.” Lock-in is a situation in which you have no choice but to pay a certain provider for some aspect of your computer services. Since computers are so fundamental to our lives, we sometimes have no choice but to pay the provider of that lock-in service.

Think of a few service providers in your life who have no serious competition. What is your relationship to that service provider? Do you feel like you are paying too much money? Do you wish that you could switch?

This is how many people feel about their Internet service provider. An Internet Service Provider is the company that provides you with the “last mile” of physical infrastructure that connects you to the rest of the Internet. Different forms of ISP include cable ISPs, satellite ISPs, fiber ISPs, and copper/DSL ISPs. The medium of delivery varies, but the functionality is the same. This company is crucial to your Internet access.

In many geographic locations, there are very restricted options for which ISP you could use. Why is that? Many people assume that there is some physical or regulatory barrier to starting an ISP. In fact, there are fewer barriers than you might think.

Adam Montgomery is a co-founder of Necto, a company that provides an ISP starter kit. If you want to start your own ISP in an apartment building or in your neighborhood or wherever you are, the Necto ISP starter kit can help you get off the ground. That might sound like a crazy idea, but in this episode Adam explains why it is not so crazy–why the technology around ISPs is more broadly accessible than many people believe.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Necto: Build an ISP with Adam Montgomery", + "Episodes Uid": "SED3011085137", + "Episodes Audio File": "0c62e13d4f4da101df36c45489319aee.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "28g", + "Episodes ID": "12a6f54e-e329-11ea-91a2-070f16bcbe80", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/simpsons_data_science_edited.mp3", + "Episodes Pubdate Date": "2016-10-18", + "Episodes Summary": "

The Simpsons is a classic, beloved television show. The scripts of The Simpsons have been made publicly available, and include dialogue, location, and character information. Todd Schneider used these scripts and other information sources as a corpus to analyze The Simpsons and find interesting statistics–such as who the most important supporting characters were, and how the ratings of the show have trended over time relative to other TV shows that have declined in ratings.

Todd works at Genius in New York, and I took the opportunity to ask him other questions about pop culture, given that Genius is a place where pop culture and data collide. If you haven’t seen the site, it started out as a wiki for rap music, and quickly grew to more aspects of pop culture.

Todd also has a variety of other side projects, involving betting markets, analysis of taxis vs Lyft and Uber, and a systematic study of the wedding section of the New York Times.

", + "Episodes Title": "Simpsons Data Science with Todd Schneider", + "Episodes Uid": "SED3152287258", + "Episodes Audio File": "d80b5dacde936fbf7cbc71a236b589af.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 621, + "Episodes ID": "eccbbd00-e328-11ea-91a2-972ff7aff8ed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_13_PS3Engineering.mp3", + "Episodes Pubdate Date": "2019-08-13", + "Episodes Summary": "

The PlayStation is a line of game consoles created by Sony. PlayStation devices include the PS2, PS3, PS4, and the PSP mobile system. Tony Godar worked as an engineer in the PlayStation ecosystem for 15 years, and he joins the show to give a retrospective on his time in the console industry.

Developing hardware and software for game consoles differs significantly from the world of web development. Tony describes the culture of the game development world, and the challenges involved in the domains of software tooling, custom operating systems, and streaming media. In 2010, the PS3 was hacked by notorious tinkerer George Hotz, a previous guest on the show, an event which Tony also discusses.

We also discuss the world of modern gaming and VR technology. Tony currently works as an engineer at MelodyVR, a company that makes virtual reality live music experiences.

", + "Episodes Title": "PlayStation Engineering with Tony Godar", + "Episodes Uid": "SED8441478276", + "Episodes Audio File": "100ac06d072a4510e739f1415cd226fe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4fq", + "Episodes ID": "f16d97f2-e328-11ea-91a2-c7aabdcb4fa2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_10_KubernetesCDwithSheroyMarker.mp3", + "Episodes Pubdate Date": "2018-09-10", + "Episodes Summary": "

Engineering organizations can operate more efficiently by working with a continuous integration and continuous deployment workflow. Continuous integration is the process of automatically building and deploying code that gets pushed to a remote repository. Continuous deployment is the process of moving that code through a pipeline of environments, from dev to test to production. At each stage, the engineers feel increasingly safe that the code will not break the user experience.

When a company adopts Kubernetes, the workflow for deploying software within that company might need to be refactored. If the company starts to deploy containers in production, and managing those containers using Kubernetes, the company will also want to have a testing pipeline that emulates the production environment using containers and Kubernetes.

Sheroy Marker is the head of technology at ThoughtWorks products, where he works on GoCD, a continuous delivery tool. Sheroy joins the show to talk about how Kubernetes affects continuous delivery workflows, and the process of building out Kubernetes integrations for GoCD.

We also discussed the landscape of continuous delivery tools–why there are so many continuous delivery tools, and the question of how to choose a continuous delivery product if you are implementing CD. Continuous delivery tooling is in some ways like the space of monitoring, logging, and analytics–there are lots of successful products in the market. Full disclosure: ThoughtWorks and GoCD are sponsors of Software Engineering Daily.

", + "Episodes Title": "Kubernetes Continuous Deployment with Sheroy Marker", + "Episodes Uid": "SED8675623965", + "Episodes Audio File": "f07a2c6a6b23785618e62a9afae123e7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ps", + "Episodes ID": "f32d16f8-e328-11ea-91a2-f30f68fdaf73", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_07_AffirmEngineering.mp3", + "Episodes Pubdate Date": "2018-05-07", + "Episodes Summary": "

When I buy a mattress online, I pay for it with my credit card. Behind the scenes, a complex series of transactions occur between a payment gateway, the credit card company, and a few banks. There are problems with this process–it is slow, complex, and involves the synchronization of several different parties.

Some consumers will not want to purchase the mattress because they do not have cash, and the lending rates they get offered are higher than they are willing to spend. If these consumers were presented with more intelligent loan rates, the lender could still make money, the mattress company could still make money, and the consumer would get a new mattress. It’s a missed opportunity all around.

Affirm is a consumer financial services company. Their first product offers loans to consumers making purchases. In today’s episode, Affirm CTO Libor Michalek explains how Affirm decided to build this product, and what they have done to scale it.

The conversation took me by surprise. Affirm was started by Max Levchin, who was a co-founder of PayPal. I assumed that when Affirm was created, they already knew exactly what they were going to build–because Affirm is a payments company and Max has had knowledge of the payments industry going back two decades. In reality, Affirm started out with more vague ideas around what they were building.

They spent some time running small experiments as they looked for product/market fit–just like a bootstrapped startup would have. It was inspiring to know that even an experienced team is willing to go through the humble process of searching for a product within a space they are deeply familiar with.

We didn’t get to all the questions I was planning to explore, but I hope to do another show about Affirm in the future.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Affirm Engineering with Libor Michalek", + "Episodes Uid": "SED8998368919", + "Episodes Audio File": "855a2492d67abaea849f59eb86dab376.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3oy", + "Episodes ID": "f3574766-e328-11ea-91a2-6bf675baac61", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_26_TensorFlowUpdates.mp3", + "Episodes Pubdate Date": "2018-04-26", + "Episodes Summary": "

Rajat Monga is a director of engineering at Google where he works on TensorFlow. TensorFlow is a framework for numerical computation developed at Google.

The majority of TensorFlow users are building machine learning applications such as image recognition, recommendation systems, and natural language processing–but TensorFlow is actually applicable to a broader range of scientific computation than just machine learning. TensorFlow has APIs for decision trees, support vector machines, and linear algebra libraries.

The current focus of the TensorFlow team is usability. There are thousands of engineers building data intensive applications with TensorFlow, but Rajat and the rest of the TensorFlow team would like to see millions more. In today’s show, Rajat and I discussed how TensorFlow is becoming more usable, as well as some of the developments in TensorFlow around edge computing, TensorFlow Hub, and TensorFlow.js, which allows TensorFlow to run in the browser.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "TensorFlow Applications with Rajat Monga", + "Episodes Uid": "SED4346007203", + "Episodes Audio File": "484100d360bf60210666d2dcffe0ee73.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 500000, + "Episodes ID": "ef384900-e328-11ea-91a2-ab9734de6f16", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_27_DarknetDiaries.mp3", + "Episodes Pubdate Date": "2019-02-27", + "Episodes Summary": "

Podcast listeners usually find out about a new podcast in one of two ways: either a friend recommends that podcast or the Apple podcast charts rank that new podcast highly.

The Apple podcast charts are created using an algorithm that is not public. Many people believe that the chart ranking of a podcast is based on the number of podcast subscribers, the number of podcast downloads, and the reviews that are written about the podcasts on iTunes.

Jack Rhysider is the host of Darknet Diaries, a podcast about the dark and strange elements of the Internet. Darknet Diaries is told in a high quality, narrative audio format. Jack is a security engineer with a deep understanding of technology, and has been blogging for a long time.

As Jack has built a following with his podcast, he has spent more time looking at the iTunes podcast charts. He has seen the rank of Darknet Diaries increase–but he has seen the rank of other podcasts increase much faster. Some of these podcasts have low quality content. The audio quality is poor, the host is unprepared–these are the kinds of podcasts you would listen to once, and never subscribe to.

And yet, numerous podcasts with low quality were somehow able to game the rankings and make it to the top of the charts.

In episode 27 of Darknet Diaries, Jack investigated the phenomenon of fraudulent podcast chart manipulation. It was one of my favorite podcast episodes ever (and this is coming from someone who has listened to a lot of podcasts). The investigation went to several unexpected places, but Jack did solve the riddle of how low quality podcasts climb the iTunes charts.

Jack joins the show to talk about fraudulent–and the broader implications of the fake Internet. Today’s episode is a simple example of how easily Internet platforms can be gamed–for a deeper dive into the fake Internet, listen to our past episodes on advertising fraud, or tomorrow’s episode with ad fraud investigative journalist Craig Silverman, which I am very excited about.

", + "Episodes Title": "Fake Podcast Charts with Jack Rhysider", + "Episodes Uid": "SED4926152035", + "Episodes Audio File": "45a62a251115cb0f0026a5a3cb686a69.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3rt", + "Episodes ID": "f311189a-e328-11ea-91a2-5f3c7b4c822b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_15_Vitess.mp3", + "Episodes Pubdate Date": "2018-05-15", + "Episodes Summary": "

YouTube runs a large MySQL database to hold the metadata about its videos. As YouTube scaled, the database was sharded, and applications within YouTube had to write queries that were aware of the sharding layout of that database.

This is problematic, because it pushes complexity to the application developer. An application developer shouldn’t have to be aware of how a database is laid out among different nodes. The developer should be able to issue a query, and have the cluster simply return the data.

Vitess is an open source system for scaling large MySQL databases. Sugu Sougoumarane co-created Vitess at YouTube. Since YouTube is owned by Google, Vitess was able to leverage the Borg cluster manager developed at Google. Once Kubernetes came to market, it became more viable to make Vitess accessible to open source developers.

Sugu joins the show to talk about the scalability problems that YouTube’s database infrastructure encountered and the motivations for building Vitess.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Vitess: Scaling MySQL with Sugu Sougoumarane", + "Episodes Uid": "SED1033020474", + "Episodes Audio File": "ab8069b6b0e0a60cadad7ef4a280db30.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3jm", + "Episodes ID": "f4229b46-e328-11ea-91a2-43bcc3c072f4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_26_BitcoinTransactions.mp3", + "Episodes Pubdate Date": "2018-02-28", + "Episodes Summary": "

Bitcoin is an immutable, append-only blockchain ledger that reaches consensus through proof-of-work. The contents of the ledger are financial transactions–people sending and receiving Bitcoin currency to each other.

Since Bitcoin, there have been other cryptocurrencies that have similar properties–like Ethereum and the IPFS/Filecoin system. Similar to Bitcoin, they use a decentralized, proof of work based system with a currency reward system–but the ledger being maintained is not purely financial. A currency is a necessary component to maintaining the blockchain’s validity.

Over the next month, we will be exploring a variety of blockchain-based technologies. Some interviews will be high-level conversations that assume only a familiarity with cryptocurrencies. Some of them will be deeply technical, and assume a strong understanding of Bitcoin and Ethereum. And some episodes, like today’s episode, will be aimed at the developer who is in the process of “going down the rabbit hole.”

If you are finding yourself reading about Bitcoin and Ethereum a few hours every day, but you are still struggling to grasp the basics, this episode is for you. It is meant to be a complement to other introductory resources, such as “Mastering Bitcoin,” by Andreas Antonopoulos.

Cryptocurrency systems are revolutionary–they will unlock completely new applications in the very near future. It’s If you are trying to understand these decentralized currencies and applications, the best place to start is with Bitcoin. That’s why I was happy to have Daniel Van Flymen back on the show.

Daniel was previously on for one of our most popular episodes–”Blockchain Building,” in which he talked about how useful it can be to build a blockchain based system for practice. Today, Daniel discusses the basics of Bitcoin transactions. What happens when you send money? How are transactions represented on the blockchain? How do full nodes and light clients interact with each other?

These are difficult topics to discuss purely over audio, so this episode is best listened to as a companion resource for someone who is studying cryptocurrencies.

If you are looking for an internship, apply to the Software Engineering Daily internship, at softwaredaily.com/jobs. And if you are looking to recruit engineers, you can post jobs for your company there as well–it’s completely free to post jobs and to apply. We are hoping to find interns to contribute to the Software Daily open source project–and if you want to see what we are building, go to SoftwareDaily.com or check out our apps in the  iOS or Android app store. They have all 650 of our episodes, with recommendations, related links, discussions and more.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Bitcoin Transactions with Daniel Van Flymen", + "Episodes Uid": "SED4555351556", + "Episodes Audio File": "4bf5d17c7908be7981c357687a63b7be.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5s1", + "Episodes ID": "ede694da-e328-11ea-91a2-37ace8978e5f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_29_NetflixEarlyDays.mp3", + "Episodes Pubdate Date": "2019-05-29", + "Episodes Summary": "

Netflix started with a DVD-by-mail product. The software infrastructure and operations practices needed for the DVD business were very different from those needed by a streaming video company.

Since the early days of Netflix, CEO Reed Hastings knew that the company would evolve to becoming a streaming video platform. But he did not know when the technology would be advanced enough to support video streaming, and he did not know how users would consume it.

Greg Burrell has worked at Netflix for 14 years. Greg was one of the first engineers to start working on video streaming, which Netflix first attempted to implement with a set top box that downloaded movies and played them on your television. After evolving this strategy, Netflix arrived at the current model of video streaming through apps on browsers and mobile devices.

As the company pivoted from DVD-by-mail to video streaming, Netflix encountered multiple challenges across engineering, operations, and communications across the company. At the time, there was no “DevOps” movement. There were not established continuous delivery practices. The available cloud technologies were immature and low level.

Greg joins the show to describe the evolutionary arc of Netflix’s engineering process. Greg also presents a model for software development that he describes as “Full Cycle Development”. At Netflix, engineering teams of full cycle developers work without dedicated operations or testing teams. It is a sophisticated approach to engineering management.

I spoke to Greg at the Fullstack Tech Radar Day, a software conference in Tel-Aviv put on by Tikal, an engineering community based out of Israel and San Francisco. This was a great conference, and we’ll be airing some additional content from it in the coming weeks.

We are hiring two interns for software engineering and business development! If you are interested in either position, send an email with your resume to jeff@softwareengineeringdaily.com with “Internship” in the subject line.

", + "Episodes Title": "Netflix Early Days with Greg Burrell", + "Episodes Uid": "SED4753782027", + "Episodes Audio File": "446b47060b3581c2a295cfae0d964df9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yu", + "Episodes ID": "f6a3720a-e328-11ea-91a2-d3c8d79f3ede", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/HealthwithCosima.mp3", + "Episodes Pubdate Date": "2017-09-01", + "Episodes Summary": "

Automation will make healthcare more efficient and less prone to error. Today, machine learning is already being used to diagnose diabetic retinopathy and improve radiology accuracy. Someday, an AI assistant will assist a doctor in working through a complicated differential diagnosis.

Our hospitals look roughly the same today as they did ten years ago, because getting new technology into the hands of doctors and nurses is a slow process–just ask anyone who has tried to sell software in the healthcare space. But technological advancement in healthcare is inevitable.

Cosima Gretton is a medical doctor and a product manager with KariusDX, a company that is building diagnostic tools for infectious diseases. She writes about the future of healthcare, exploring the ways that workflows will change and how human biases could impact the diagnostic process–even in the presence of sophisticated AI.

", + "Episodes Title": "Healthcare AI with Cosima Gretton", + "Episodes Uid": "SED5011441162", + "Episodes Audio File": "5c27f302cf1f6e8a8dcbefcabde42223.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5n2", + "Episodes ID": "ee5d8298-e328-11ea-91a2-63709bdb2e6f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_25_Intricately.mp3", + "Episodes Pubdate Date": "2019-04-25", + "Episodes Summary": "

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

Intricately is a company that maps the breadth and depth of cloud infrastructure usage. Using a combination of clever algorithms, data engineering, and web crawlers, Intricately derives information about how different companies spend money on infrastructure.

Fima Leshinsky is the CEO and co-founder at Intricately. In his previous job at Akamai, he began to study how a cloud provider such as Akamai could figure out how much its competitors were charging certain customers. Since CDN infrastructure is a commodity with reasonably low switching cost, a provider that can undercut its competitors significantly can have an edge in the marketplace.

From his work at Akamai, Fima felt there was a market opportunity to provide this kind of service to the broader market of cloud providers. There are more cloud providers than ever before, and the kind of data that Intricately aggregates is highly useful to this competitive marketplace.

Fima joins the show to talk about the modern landscape of cloud providers, and how to build a system that maps the Internet.

", + "Episodes Title": "Intricately: Mapping the Internet with Fima Leshinsky", + "Episodes Uid": "SED8257755889", + "Episodes Audio File": "097a7aedefc8c364fd19ce9b0b68b600.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "51i", + "Episodes ID": "f04d9c0a-e328-11ea-91a2-57c800a3026b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_04_StreamingPlatformArchitecture.mp3", + "Episodes Pubdate Date": "2018-12-04", + "Episodes Summary": "

Demand for live streaming video over the internet is increasing. After the emergence of early live streaming platforms, like Twitch and Facebook Live, more forms of video have become accessible over live streams, such as sports. Live streaming is a harder engineering problem than delivering a static video file because the information distributed on a live stream is constantly changing.

DZN, spelled D-Z-N, is a live streaming service for watching fight events, such as boxing. The workloads for live streaming can be highly bursty. When a fight is scheduled to happen, the vast
\nmajority of traffic will hop on to watch the fight 20 seconds before the fight starts. A huge number of users logs into DZN and starts watching all at the same time. This quick spike in traffic means that DZN has to have servers spun up and be ready in advance.

Luca Mezzarlira and Yan Cui are engineers at DZN. Yan was previously on the show in a few amazing episodes to talk about serverless infrastructure and the complexities of real-time video game software development. Those episode links are in the show notes. I highly recommend checking them out. Today’s show is a discussion of architecting a system to handle a high bandwidth customer use case. I hope you like it.

", + "Episodes Title": "Streaming Platform Architecture with Luca Mezzarlira and Yan Cui", + "Episodes Uid": "SED8074157885", + "Episodes Audio File": "96a1824d224628f60ff935f133bd3eea.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5tr", + "Episodes ID": "edb9cb30-e328-11ea-91a2-b332c7dd2ade", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_11_KubernetesVisionwithJoeBeda.mp3", + "Episodes Pubdate Date": "2019-06-11", + "Episodes Summary": "

Google Cloud was started with a vision of providing Google infrastructure to the masses.

In 2008, it was not obvious that Google should become a cloud provider. Amazon Web Services was finding success among startups who needed on-demand infrastructure, but the traditional enterprise market was not yet ready to buy cloud resources.

Googlers liked the idea of becoming a cloud provider. But was it the right time to enter the market? Google’s advertising business was a large and growing cash cow. Executives within Google were not sure how much capital and effort should be allocated into an infrastructure business.

When Google decided to go into the cloud business, Joe Beda was one of the engineers who helped lead the effort, and joins the show as today’s guest.

Google’s internal server infrastructure is managed by Borg, a system for allocating resources to applications. Google Cloud runs on Borg, and there were a number of early engineering challenges to building the necessary functionality into Borg for running a cloud provider on top of it.

One example of a technical challenge that Google faced was the refactoring of Borg to run Google Cloud workloads.

The requirements for public infrastructure are different than those of internal Googlers. Inside of Google, developers deploy their applications to containers running on bare metal. Outside of Google, developers want to create virtual machines. Borg needed to be refactored in order to instantiate VMs.

Google solved this technical problem, as well as many other challenges, and Google Cloud slowly gained momentum in the market. But AWS remained the default choice for profitable enterprise workloads. It wasn’t until the container orchestration wars that Google found an opportunity to jump on a market segment that offered strong differentiation.

By open sourcing Kubernetes and presenting a clear vision for where the project was going, Google shifted the battlefield of the public cloud toward a competitive landscape where it has many advantages. Kubernetes also provided many other technology companies with an opportunity to get into the cloud market, creating a collaborative, multi-company ecosystem that has accelerated the pace of software faster than anyone expected.

Joe Beda has been instrumental in the evolution of the cloud native ecosystem. In today’s episode, Joe gives his memories on Google Cloud, Kubernetes, and his Kubernetes company Heptio, which he sold to VMware.

", + "Episodes Title": "Kubernetes Vision with Joe Beda", + "Episodes Uid": "SED8621106816", + "Episodes Audio File": "653cbfad09b4a586baa9ed3b415f5c3e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3eo", + "Episodes ID": "f4b9c02a-e328-11ea-91a2-230cd1ea6ae2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_18_RookKubernetesStorage.mp3", + "Episodes Pubdate Date": "2018-01-18", + "Episodes Summary": "

Modern applications store most of their data on hosted storage solutions. We use hosted block storage to back databases, hosted object storage for objects such as videos, and hosted file storage for file systems. Using a cloud provider for these storage systems can simplify scalability, durability, and availability–it can be less painful than taking care of storage yourself.

One downside: the storage systems offered by the cloud providers are not open source. The APIs might vary from provider to provider. Wiring your application to a particular storage service on a particular cloud could tightly couple you to that cloud.

Rook is a project for managing storage, built on Kubernetes. If you use a Rook cluster for your storage, you can port that storage model to any cloud, and have a consistent API for object, block, and file storage. In this episode, Bassam Tabbara describes the state of cloud storage, and why he started the Rook project.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kubernetes Storage with Bassam Tabbara", + "Episodes Uid": "SED2960069181", + "Episodes Audio File": "79163cc50e13427edc957c37e63f546a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2u2", + "Episodes ID": "f80d994a-e328-11ea-91a2-0ba865a3c748", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/InstacartDataScience.mp3", + "Episodes Pubdate Date": "2017-06-29", + "Episodes Summary": "

Instacart is a grocery delivery service. Customers log onto the website or mobile app and pick their groceries. Shoppers at the store get those groceries off the shelves. Drivers pick up the groceries and drive them to the customer. This is an infinitely complex set of logistics problems, paired with a rich data set given by the popularity of Instacart.

Jeremy Stanley is the VP of data science for Instacart. In this episode, he explains how Instacart’s 4-sided marketplace business is constructed, and how the different data science teams break down problems like finding the fastest route to groceries within a store, finding the best path to delivering groceries from a store to a user, and personalizing recommendations so people can find new items to try.

Are you looking for old episodes of Software Engineering Daily, but don’t know how to find the ones that are interesting to you? Check out our new topic feeds, in iTunes or wherever you find your podcasts. We’ve sorted all 500 of our old episodes into categories like business, blockchain, cloud engineering, JavaScript, machine learning, and greatest hits. Whatever specific area of software you are curious about, we have a feed for you. Check the show notes for more details.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Instacart Data Science with Jeremy Stanley", + "Episodes Uid": "SED5318734426", + "Episodes Audio File": "467580e035d3d6403c1a946f4d05c126.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1su", + "Episodes ID": "1fd6c10e-e329-11ea-91a2-5bea522dcd20", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/greyorange_final.mp3", + "Episodes Pubdate Date": "2016-03-27", + "Episodes Summary": "

GreyOrange Robotics builds robots for warehouse automation of logistics and ecommerce companies for quicker deliveries. Today’s episode features Akash Gupta, the CTO of GreyOrange.

", + "Episodes Title": "Robots in the Warehouse with Akash Gupta", + "Episodes Uid": "SED2484063135", + "Episodes Audio File": "dcada8e66651d4e6afd3e74eed7d1d80.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "46j", + "Episodes ID": "f243eeb0-e328-11ea-91a2-1fc460acbdc3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_12_Ballerina.mp3", + "Episodes Pubdate Date": "2018-07-12", + "Episodes Summary": "

Modern programming requires lots of integration between APIs. Some of these integrations are trivial–such as using Twilio or Stripe. But there are many more complex integrations.

For example, when a large company acquires a smaller company, the acquiring company might want to integrate with that smaller company to leverage the synergies between the two companies. How do you build clean communication patterns between the services of one company and another?

Two teams within a single enterprise can also have integration issues. One team might have a different data model than the other team. One team might be using JSON and the other using XML. In these cases, integrations between APIs can take considerable time.

Ballerina is a programming language that is designed for writing integrations. Ballerina is made for building services that allow two APIs to communicate easily–in contrast to other patterns of API integration such as those involving an enterprise service bus.

Tyler Jewell is the CEO of WSO2, a company that specializes in integrations. WSO2 created the Ballerina language and is investing heavily into it (with ~80 people working on Ballerina today). In this episode we explored integrations–and why this problem required creating a new programming language.

BallerinaCon is July 18th in San Francisco and our listeners can attend for free–use code BalCon-SEDaily.

", + "Episodes Title": "Ballerina Language with Tyler Jewell", + "Episodes Uid": "SED9830435177", + "Episodes Audio File": "95316ffea539fc0d93b2c422ea2745c4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "54t", + "Episodes ID": "f011075e-e328-11ea-91a2-df4c7929ebe0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_21_Rockset.mp3", + "Episodes Pubdate Date": "2018-12-21", + "Episodes Summary": "

At Facebook, Venkat Venkataramani saw how large volumes of data were changing software infrastructure. Applications such as logging servers and advertising were creating fast moving, semi-structured data. The user base was growing, the traffic was growing, and the volume of data was growing. And the popular methods for managing this data were insufficient for the applications that developers wanted to build on top.

In previous episodes about data platforms, we have covered similar difficulties as experienced by Uber and Doordash. Incoming data is often in JSON, which is hard to query. The data is transformed to a file format like Parquet, which requires an ETL job. Once it is in a Parquet file on disk in a data lake, the access time is slow. To query the data efficiently, it must be loaded into a data warehouse, which loads the data into memory, often in a columnar format that is easy to aggregate.

Imagine being a developer at Facebook, Uber, or Doordash, and trying to build a simple dashboard, or a machine learning application on top of this data platform. Where do you find the right data? How do you know it is up to date? And what if you don’t know the shape of your queries ahead of time, and you haven’t defined indexes over your data? The access speed will be too slow to do exploratory analysis.

There are so many steps in this process, and each of these steps creates friction for application developers that want to build on top of “big data”. Since even Facebook was having trouble managing this problem of the data platform, Venkat figured there was an opportunity to build a company around solving the data platform for other software companies.

Venkat is the CEO of Rockset, a data system that is built to make it easy for developers to build data-driven apps. In Rockset, data can be ingested from data streams, data lakes, and databases. Rockset creates multiple indexes and schemas across the data. Because there are multiple models for querying, Rockset can analyze an incoming query and create an intelligent query plan for serving it.

Venkat joins the show to discuss his time working on data at Facebook, the untapped opportunities of using that data, and the architecture of Rockset.

", + "Episodes Title": "Rockset Data Platform with Venkat Venkataramani", + "Episodes Uid": "SED3903231639", + "Episodes Audio File": "5c58a0e7c860b637e0df73a88af01ded.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 520, + "Episodes ID": "f04482f0-e328-11ea-91a2-fb873ce30c5c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_06_RapidAPI.mp3", + "Episodes Pubdate Date": "2018-12-06", + "Episodes Summary": "

Building software was simplified by cloud providers. With the cloud, it became much easier to deploy a server, spin up a database, and scale an application. Cloud providers like AWS gave developers access to these infrastructure primitives like storage and compute.

On top of those primitives, numerous API companies have been built. An API company offers a more specific set of services. Twilio offers SMS text messaging API services. Stripe offers payment API services. These APIs give developers another level of tooling to build software out of.

Developers can now think of entire applications in terms of APIs, and the number of APIs is growing rapidly. From business services such as booking a flight to machine learning models like image classification, the “API economy” has given developers a huge catalog of tools.

Since developers have this additional leverage, software can be built with smaller teams. The codebase can also be smaller. But one area where the complexity is growing is the number of APIs that need to be managed. For each API, there is a different system for integrating the API into your application. Different API providers have different levels of reliability.

Another area of difficulty is the discoverability of APIs. If I don’t know about a flight search API, I am never going to think of what applications I could build on top of that. There are APIs for generating memes, and APIs for easily querying what music is trending across the world.

RapidAPI is a marketplace for APIs. It includes search and discovery features for the wide variety of different APIs that can be found across the internet. RapidAPI is also a system for integrating with multiple APIs through it’s API management system.

Iddo Gino is the CEO and founder of RapidAPI, and he joins the show to discuss the motivation for creating an API marketplace, as well as the engineering behind RapidAPI.

", + "Episodes Title": "RapidAPI: API Marketplace with Iddo Gino", + "Episodes Uid": "SED2444911556", + "Episodes Audio File": "e46ea021e190825255b30bde19461026.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "35d", + "Episodes ID": "f5ffc858-e328-11ea-91a2-c37c0f086845", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Interviewing-io.mp3", + "Episodes Pubdate Date": "2017-10-19", + "Episodes Summary": "

Interviewing engineers is not a solved problem. Quite the opposite–everyone in the software industry will tell you their own personal issues with the hiring process.

One reason that technical interviews have not evolved significantly is the lack of standardized tooling. Some companies give you one phone screen, some give you two. Some companies have you solve brain teasers (“how many golf balls fit in a school bus”) and some make you fix bugs in their production codebase. During the on-site interview, some companies use whiteboards, some let you use a laptop.

Software companies do so much–they should be outsourcing the things that are not their core competency. Certainly they cannot outsource the entire hiring process–but they can outsource parts of it to a company like Interviewing.io.

Engineers come to Interviewing.io to practice their interview skills, where other engineers from top companies practice with them as an interviewer. When an engineer has practiced interviewing enough, they can use Interviewing.io to interview for real with real companies and find a job.

Aline Lerner is the CEO of Interviewing.io, and she knows about the software interviewing and recruiting process as much as anyone. After working as an engineer, she started studying recruiting, consulting with top companies to help them improve their process. From her observations, she created Interviewing.io. In this episode, we dissect the workflow that she created for engineers to improve at interviewing and find jobs, and also explore the insights that led her to starting Interviewing.io.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Interviewing.io with Aline Lerner", + "Episodes Uid": "SED5973918849", + "Episodes Audio File": "ec6bc70c2ac973a36b8ebdd802965fb4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5v7", + "Episodes ID": "ed8b4bfc-e328-11ea-91a2-5be5800b2435", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_25_AirflowinPractice.mp3", + "Episodes Pubdate Date": "2019-06-25", + "Episodes Summary": "

Apache Airflow is a system for scheduling and monitoring workflows for data engineering. Airflow can be used to schedule ETL jobs, machine learning work, and script execution. Airflow also gives a developer a high level view into the graph of dependencies for their data pipelines.

Chaim Turkel is a backend data architect at Tikal. He joins the show to discuss a case study of using Airflow to rearchitect the data engineering workflow of a complex financial application. We discussed the problems that Airflow solves and the process of porting existing workflows to Airflow.

", + "Episodes Title": "Airflow in Practice with Chaim Turkel", + "Episodes Uid": "SED8368452824", + "Episodes Audio File": "3933a1b157ec5803f24cffbf0faddd93.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5r5", + "Episodes ID": "edffcbd0-e328-11ea-91a2-5b3439bd67f2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_21_Intuit.mp3", + "Episodes Pubdate Date": "2019-05-21", + "Episodes Summary": "

Alex Balazs is the Intuit Chief Architect and has been working at the company for almost twenty years.

Intuit’s products include QuickBooks, TurboTax, and Mint. These applications are used to file taxes, manage business invoices, conduct personal accounting, and other critical aspects of a user’s financial life. Because the applications are managing money for users, there is not much room for error.

When Intuit was started, the company made desktop software. In his time at Intuit, Alex played a key role in rearchitecting the monolithic desktop applications to be resilient, reliable web applications. Intuit originally managed this software on their own servers. Since then, Intuit has migrated to the cloud using AWS.

Alex joins the show to discuss his experience scaling Intuit, his strategy for cloud migration, and his evaluation criteria for questions of build versus buy.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Scaling Intuit with Alex Balazs", + "Episodes Uid": "SED9336968869", + "Episodes Audio File": "c4b09e20f643bc2d8d91e918bbe9e00a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5os", + "Episodes ID": "ee35c294-e328-11ea-91a2-c7ce1dfdc338", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_06_CloudDatabasesatHeroku.mp3", + "Episodes Pubdate Date": "2019-05-06", + "Episodes Summary": "

Relational databases such as Postgres are often used for critical workloads, such as user account data. To run a relational database service in the cloud requires a cloud provider to set up a highly durable, highly available system.

Jon Daniel is an infrastructure engineer at Heroku. Jon joins the show to describe the engineering and operations required to build a managed relational database service. Full disclosure: Heroku is a sponsor of Software Engineering Daily.

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Cloud Database Workloads with Jon Daniel", + "Episodes Uid": "SED6537107177", + "Episodes Audio File": "685b487bc631cdbc913bacf48a59f4a9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6h0", + "Episodes ID": "eb6afbb0-e328-11ea-91a2-7f0fe1aa4bef", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_04_Kong.mp3", + "Episodes Pubdate Date": "2019-11-27", + "Episodes Summary": "

Originally published January 4, 2019

When a user makes a request to product like The New York Times, that request hits an API gateway. An API gateway is the entry point for an external request. An API gateway serves several purposes: authentication, security, routing, load balancing, and logging.

API gateways have grown in popularity as applications have become more distributed, and companies offer a wider variety of services. If an API is public, and anyone can access it, you might need to apply rate limiting so that users cannot spam the API. If the API is private, the user needs to be authenticated before the request is fulfilled.

Kong is a company that builds infrastructure for API management. The Kong API gateway is a widely used open source project, and Kong is a company built around supporting and building on top of the API gateway.

Marco Palladino is the co-founder and CTO of Kong. He joins the show to tell the story of starting Kong eight years ago, and how the API gateway product evolved out of an API marketplace. Marco also discusses the architecture of Kong and his vision for how the product will develop in the future–including the Kong service mesh.

", + "Episodes Title": "Kong API Platform with Marco Palladino Holiday Repeat", + "Episodes Uid": "SED8278139792", + "Episodes Audio File": "3f08faa51a6e6daeebc31a09541c532d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "51v", + "Episodes ID": "f0496a04-e328-11ea-91a2-83e076b6da65", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_05_LightningNetwork.mp3", + "Episodes Pubdate Date": "2018-12-05", + "Episodes Summary": "

The Bitcoin main chain is a large distributed ledger of transactions. Bitcoin is useful for maintaining a trusted record of payments, but is not practical for small day-to-day payments.

Bitcoin payment channels allow users to issue small payments to each other without paying the high transaction cost and latency of going through the main chain. When payment channels are connected to each other, a “lightning network” is formed. Lightning network is often referred to as a “second layer” scalability solution.

Alex Bosworth is a lightning infrastructure lead at Lightning Labs, a company that builds infrastructure for scaling blockchains. In today’s show, Alex explains how Bitcoin payment channels work, and provides some context on how developed the modern infrastructure is in terms of practical use cases for Bitcoin.

", + "Episodes Title": "Bitcoin Payment Channels with Alex Bosworth", + "Episodes Uid": "SED1715142555", + "Episodes Audio File": "7cd2e2725d3ff2bce0fdda0a5a16890a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5so", + "Episodes ID": "edc8bafa-e328-11ea-91a2-3394cf2c5b31", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_06_ContainerComputewithLachlanEvenson.mp3", + "Episodes Pubdate Date": "2019-06-06", + "Episodes Summary": "

Containers offer a lightweight abstraction for running a server. Cloud providers are able to manage billions of containers from different users, allowing for economies of scale so that each user can pay less.

Today, there is a variety of ways that users can deploy containers on a cloud provider. These containers can run in managed Kubernetes clusters, in functions-as-a-service, or in long-lived standalone container instances. User preferences are getting more sophisticated, with some users showing an interest in Knative, an open source serverless system originally created at Google.

Whichever container deployment system you choose, your application and its multiple servers need a way to route traffic, measure telemetry, and configure security policy. A service mesh abstraction can help serve these use cases.

Lachlan Evenson has worked in containers and Kubernetes since before the container orchestration wars. He was an engineer at Deis, a company which built an open source platform-as-a-service running on top of containers and Kubernetes. Deis was acquired by Microsoft, where Lachlan now works as principal program manager of Container Compute.

Lachlan joins the show to discuss containers, Kubernetes, and the Service Mesh Interface, an interoperable service mesh layer that Microsoft launched with Buoyant.

", + "Episodes Title": "Service Mesh Interface with Lachlan Evenson", + "Episodes Uid": "SED8277386605", + "Episodes Audio File": "213cb732f468fa6b02525c25e8a6c2f2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 564, + "Episodes ID": "efeb9f6e-e328-11ea-91a2-ff6abf21e690", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_04_Kong.mp3", + "Episodes Pubdate Date": "2019-01-04", + "Episodes Summary": "

When a user makes a request to product like The New York Times, that request hits an API gateway. An API gateway is the entry point for an external request. An API gateway serves several purposes: authentication, security, routing, load balancing, and logging.

API gateways have grown in popularity as applications have become more distributed, and companies offer a wider variety of services. If an API is public, and anyone can access it, you might need to apply rate limiting so that users cannot spam the API. If the API is private, the user needs to be authenticated before the request is fulfilled.

Kong is a company that builds infrastructure for API management. The Kong API gateway is a widely used open source project, and Kong is a company built around supporting and building on top of the API gateway.

Marco Palladino is the co-founder and CTO of Kong. He joins the show to tell the story of starting Kong eight years ago, and how the API gateway product evolved out of an API marketplace. Marco also discusses the architecture of Kong and his vision for how the product will develop in the future–including the Kong service mesh.

", + "Episodes Title": "Kong API Platform with Marco Palladino", + "Episodes Uid": "SED7023677178", + "Episodes Audio File": "3f08faa51a6e6daeebc31a09541c532d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3pu", + "Episodes ID": "f323e038-e328-11ea-91a2-83e43e8bedb0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_09_DataEngineeringwithTobiasMacey.mp3", + "Episodes Pubdate Date": "2018-05-09", + "Episodes Summary": "

Cloud computing lowered the cost and improved accessibility to tools for storing large volumes of data. In the early 2000s, Hadoop caused a revolution in large scale batch processing. Since then, companies have been building ways to store and access their data faster and more efficiently.

At the same time, the sheer volume of data has increased and machine learning has given rise to methods of extracting signal from seemingly inconsequential data points. This confluence of factors gave rise to the role of the data engineer. A data engineer defines the data pipeline and supports data scientists and machine learning engineers.

Tobias Macey hosts the “Data Engineering Podcast,” where he covers the fast moving world of data engineering–including databases, cloud providers, and open source tools. Tobias and I covered a range of topics in the data engineering space and also spent significant time discussing the world of software engineering podcasting.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Data Engineering Podcast with Tobias Macey", + "Episodes Uid": "SED4766680910", + "Episodes Audio File": "34c0d8a571112c4099004e2d28162f9d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32s", + "Episodes ID": "f640c9a2-e328-11ea-91a2-e7b254b20e66", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SportsAnalytics.mp3", + "Episodes Pubdate Date": "2017-09-29", + "Episodes Summary": "

A basketball game gives off endless amounts of data. Cameras from all angles capture the players making their way around the court, dribbling, passing, and shooting. With computer vision, a computer can build a well-defined understanding for what a sport looks like. With other machine learning techniques, the computer can make predictions by combining historical data with a game that is going on right now.

Second Spectrum is a company that builds products for analyzing sports. At major basketball arenas, Second Spectrum cameras sit above the court, recording the game and feeding that information to the cloud. Second Spectrum’s servers crunch on the raw data, processing it through computer vision and putting it into deep learning models. The output can be utilized by teams, coaches, and fans.

Yu-Han Chang and Jeff Su are co-founders of Second Spectrum. They join the show to describe the data pipeline of Second Spectrum from the cameras on the basketball court to the entertaining visualizations. After talking to them, I am convinced that machine learning will completely change how sports are played–and will probably open up a platform for new sports to be invented.

The iOS app is the first project to come out of the Software Engineering Daily Open Source Project. There are more projects on the way, and we are looking for contributors–if you want to help build a better SE Daily experience, check out github.com/softwareengineeringdaily. We are working on an Android app, the iOS app, a recommendation system, and a web frontend. Help us build a new way to consume software engineering content at github.com/softwareengineeringdaily.

", + "Episodes Title": "Sports Deep Learning with Yu-Han Chang and Jeff Su", + "Episodes Uid": "SED6075920870", + "Episodes Audio File": "b50180e709e76a3891819bdbd185d508.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2pn", + "Episodes ID": "fb91b5ba-e328-11ea-91a2-6ff8db667416", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Artsy.mp3", + "Episodes Pubdate Date": "2017-05-15", + "Episodes Summary": "

Artsy is an online art marketplace. This might sound like a simple engineering problem–you just set up a basic ecommerce site, list some pieces of art, and start making money, right?

The art world is complicated. There are four major pillars: patrons, art fairs, galleries, and auctions. Bringing these different parts online is not trivial. And in order to do so, Artsy has to work with the existing ecosystem. It is not like the taxi industry, where you can aggressively compete against the pre-existing businesses. The art world is built around relationships and trust.

The engineering is hard too. An art auction results in a transaction for millions of dollars. In this way, building an auction system is like building a trading system. Latency needs to be very low, and you can’t make any mistakes or else customers could suffer to the tune of millions of dollars.

Daniel Doubrovkine is the CTO of Artsy, and he joins me to describe the complexities of the art market and the engineering challenges that come with building a software company around it.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Artsy with Daniel Doubrovkine", + "Episodes Uid": "SED5311347450", + "Episodes Audio File": "a7cb8135d895ec12290820b4d376cfdf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3iv", + "Episodes ID": "f43237fe-e328-11ea-91a2-8712c131cd4d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_23_VMWareCTO.mp3", + "Episodes Pubdate Date": "2018-02-23", + "Episodes Summary": "

Steve Herrod led engineering at VMWare as the company scaled from 30 engineers to 3,000 engineers. After 11 years, he left to become a managing director for General Catalyst, a venture capital firm. Since he has both operating experience and a wide view of the technology landscape as an investor, he is well-equipped to discuss a topic that we have been covering on Software Engineering Daily: the integration of cloud and edge computing.

Today, we think of the cloud as a network of large data centers operated by big players like Google, Amazon, and Microsoft. The cloud is where most of the computation across the world takes place. My smartphone and laptop are “edge” devices. They are lightweight computers that don’t perform much complex processing. I would not be able to run a large production database or a 3 terabyte MapReduce job on my laptop.

The current division of labor makes sense in this world of smart clouds and low-power, low-bandwidth devices. But the devices are getting cheaper, smarter, and more proliferate. Cars, drones, security cameras, sensors and other devices can serve as points of computation that are geographically between the edge devices and the cloud. With more devices between you and the cloud, there is an opportunity to put computation on those devices.

Everyone knows that cloud and edge computing will become intermingled in the coming years. But predicting just how it will play out is nearly impossible. And as an investor, if you bet on something too early, you get the same result as someone who was wrong altogether.

A good analogy for the “cloud and edge” space of investments might be the “smart home.” Everyone knows the smart home is coming eventually, but it’s very hard to tell how long it will be before smart home systems are in widespread use–so it is an open question how to invest in the space.

Summer internship applications to Software Engineering Daily are also being accepted. If you are interested in working with us on the Software Engineering Daily open source project full-time this Summer, send an application to internships@softwareengineeringdaily.com. We’d love to hear from you.

If you haven’t seen what we are building, check out softwaredaily.com, or download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cloud and Edge with Steve Herrod", + "Episodes Uid": "SED8851235691", + "Episodes Audio File": "01107350031eee919bc7dca9efed6446.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "34w", + "Episodes ID": "f608ff5e-e328-11ea-91a2-9f1b34080ae8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/InternetMonitoring.mp3", + "Episodes Pubdate Date": "2017-10-17", + "Episodes Summary": "

How would you build a system for indexing and monitoring the entire Internet?

Start by breaking the Internet up into IP address ranges. Give each of those address ranges to servers distributed around the world. On each of those servers, iterate through your list of IP addresses, sending packets to them. Depending on what sorts of packets those IP addresses respond to, and what those responses are, you can build a map of the devices on the Internet: what is running on those devices, and what they respond to.

Qadium is a company that indexes and monitors devices on the Internet, to help organizations understand the devices that are within corporate networks. If you are a large corporation, Qadium can probably do a better job of figuring out your Internet footprint than you can.

Matt Kraning is the CTO of Qadium, and in today’s show he describes the process by which Qadium maps the Internet. Matt used to work on data infrastructure at DARPA, and has deployed Hadoop in Afghanistan–so the infrastructure of Qadium seems relatively manageable. Our data conversations in this episode spam from talking about Storm and Hadoop to Google BigQuery, BigTable, and DataFlow.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Internet Monitoring with Matt Kraning", + "Episodes Uid": "SED7109019041", + "Episodes Audio File": "2c3bcecaa6c5414c2daf758d2cb11e5a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ru", + "Episodes ID": "f30ca06c-e328-11ea-91a2-9ffe1340d4fe", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_16_Gloo.mp3", + "Episodes Pubdate Date": "2018-05-16", + "Episodes Summary": "

Gloo is a function gateway built on top of the popular open source project Envoy. The goal of Gloo is to decouple client-facing APIs from upstream APIs. Gloo is similar to an API gateway, which is a tool that software companies can use to collect all their APIs and one place and impose security, monitoring, and other standards around those APIs.

The goal of Gloo is to provide all the tools necessary to glue together traditional and cloud-native applications. Idit Levine is the CEO of Solo.io, a company that is building Gloo and several other projects.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Gloo: Function Gateway with Idit Levine", + "Episodes Uid": "SED4688654124", + "Episodes Audio File": "ef9f1e2dee2bb01191d096015ccb2972.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 376, + "Episodes ID": "f5bc1dba-e328-11ea-91a2-af363eeaa6ff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/NetflixServerless.mp3", + "Episodes Pubdate Date": "2017-11-07", + "Episodes Summary": "

The Netflix API is accessed by developers who build for over 1000 device types: TVs, smartphontes, VR headsets, laptops. If it has a screen, it can probably run Netflix. On each of these different devices, the Netflix experience is different. Different screen sizes mean there is variable space to display the content.

When you open up Netflix, you want to efficiently browse through movies. The frontend engineers who are building different experiences for different device types need to make different requests to the backend to fetch the right amount of data. This was the engineering problem that Vasanth Asokan and his team at Netflix was tasked with solving: how do you enable lots of different frontend engineers to get whatever they need from the backend?

This problem led to the development of a “serverless-like platform” within Netflix, which Vasanth wrote about in a few popular articles on Medium. This platform enables frontend developers to write and deploy backend scripts to fetch data, decoupling the responsibilities of frontend engineers and backend engineers.

The tight coupling of frontend and backend engineering was problematic to the development velocity of Netflix.

We have done many shows about Netflix engineering, covering topics like data engineering, user interface design, and performance monitoring. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Netflix Serverless-like Platform with Vasanth Asokan", + "Episodes Uid": "SED7365334202", + "Episodes Audio File": "1fdce088f6699e96420c5fd7dac12d81.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3kx", + "Episodes ID": "f3edceb6-e328-11ea-91a2-9b3b5086ae49", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_15_Santiment.mp3", + "Episodes Pubdate Date": "2018-03-15", + "Episodes Summary": "

In the finance industry, many people have a computer on their desk called a Bloomberg terminal. A Bloomberg terminal contains news, stock prices, communication tools, and other features that make it worth a high subscription price. And people in finance can afford to pay that high subscription because their decisions can cause a gain or loss of thousands of dollars.

Cryptocurrency investors have a similar set of informational problems as traditional financiers. There is a flood of information. Financial quotes are inconsistent across different exchanges. Opinions from Twitter and reddit can be tremendously useful—if they are captured and leveraged correctly.

Santiment is a platform that is working to build a Bloomberg terminal for the cryptocurrency investor. Santiment has raised 45k Ether in their ICO last July, which was originally an amount equal to ~$11m.

Valentin Mihov is the CTO of Santiment, and he joins the show to explain what Santiment’s product does, and how the token holders will ultimately derive value from Santiment’s ecosystem.

If you are looking for an internship, apply to the Software Engineering Daily internship, at softwaredaily.com/jobs. And if you are looking to recruit engineers, you can post jobs for your company there as well–it’s completely free to post jobs and to apply. We are hoping to find interns to contribute to the Software Daily open source project–and if you want to see what we are building, go to SoftwareDaily.com or check out our apps in the  iOS or Android app store. They have all 650 of our episodes, with recommendations, related links, discussions and more.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Crypto Bloomberg with Valentin Mihov", + "Episodes Uid": "SED5926213888", + "Episodes Audio File": "992aa2a7fecd25c71629924c1177e913.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5b1", + "Episodes ID": "ef78adb0-e328-11ea-91a2-37d54303e0db", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_07_BradMeiseles.mp3", + "Episodes Pubdate Date": "2019-02-07", + "Episodes Summary": "

Virtualization software allows companies to get better utilization from their physical servers. A single physical host can manage multiple virtual machines using a hypervisor. VMware brought virtualization software to market, creating popular tools for allowing enterprises to deploy virtual machines throughout their organization.

Containers provide another improvement to server utilization. A virtual machine can be broken up into containers, allowing multiple services to run within a single VM. Containers proliferated after the popularization of Docker, and the Kubernetes open source container orchestration system grew to be the most common way of managing the large numbers of containers that were running throughout an organization.

As Kubernetes has risen to prominence, software infrastructure companies have developed Kubernetes services to allow enterprises to use Kubernetes more easily. VMware’s PKS is one example of a managed Kubernetes service.

Brad Meiseles is a senior director of engineering at VMware with more than nine years of experience with the company. He joins the show to discuss virtualization, Kubernetes, containers, and the strategy of a large infrastructure provider like VMware.

", + "Episodes Title": "VMware Kubernetes Strategy with Brad Meiseles", + "Episodes Uid": "SED9851725374", + "Episodes Audio File": "958c7835137b8a711d0b881004a13f3f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 534, + "Episodes ID": "f03629f8-e328-11ea-91a2-830d7fb22cb5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_11_FeatureFlags.mp3", + "Episodes Pubdate Date": "2018-12-11", + "Episodes Summary": "

Releasing software has inherent risk. If your users don’t like your new feature, they might stop using your product immediately. If a software bug makes it into production, it can crash your entire application.

Releasing software gradually has many benefits. A slow rollout to an increasing population of users allows you to test your software in multiple real-world environments before it goes live to everyone. A system of AB testing different versions of your software lets you see how different flavors of your software perform against similar audiences.

Edith Harbaugh is the CEO of LaunchDarkly, a system for feature management. LaunchDarkly allows developers to deploy new software releases in a controlled fashion. Edith joins the show to discuss how to implement feature flagging, and why an intelligent release process can lead to a more scientific, predictable environment for software development. Edith is also the host of To Be Continuous, a podcast about continuous delivery, software engineering, and DevOps.

", + "Episodes Title": "Feature Flags with Edith Harbaugh", + "Episodes Uid": "SED3870764433", + "Episodes Audio File": "c8083f951413dad25267e97aa8f6ff5a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3oh", + "Episodes ID": "f37ba7b4-e328-11ea-91a2-03f501820c70", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_17_TalkingBitcoin.mp3", + "Episodes Pubdate Date": "2018-04-17", + "Episodes Summary": "

Let’s Talk Bitcoin is one of the most popular podcasts about cryptocurrencies. Adam B. Levine started it after three other podcasts he started did not get the traction he had hoped for. Adam parlayed the success of Let’s Talk Bitcoin into a network of podcasts–the Let’s Talk Bitcoin Network–which also includes one of my favorite shows, Epicenter.

Adam joins me on today’s episode for a discussion of so many topics: the culture around cryptocurrencies, the art of podcasting, blockchain scalability, and ICOs. The conversation around ICOs was particularly exciting–if you have been listening to recent episodes, you have heard interviews with companies who have done ICOs.

Some ICO companies are now facing legal ramifications for their token sales–and Adam and I have some disagreement over whether these ICO companies deserve much sympathy. It was a debate that I enjoyed and I hope to have Adam back on the show in the future for more debates.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Talking Bitcoin with Adam B. Levine", + "Episodes Uid": "SED7592744460", + "Episodes Audio File": "8372900ec7fbbfa8d7b471c838a13870.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4d1", + "Episodes ID": "f1892b98-e328-11ea-91a2-13ef42931515", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_30_ContainersandKubernetesImpact.mp3", + "Episodes Pubdate Date": "2018-08-30", + "Episodes Summary": "

Engineering organizations can operate more efficiently by working with a continuous integration and continuous deployment workflow. Continuous integration is the process of automatically building and deploying code that gets pushed to a remote repository. Continuous deployment is the process of moving that code through a pipeline of environments, from dev to test to production. At each stage, the engineers feel increasingly safe that the code will not break the user experience.

When a company adopts Kubernetes, the workflow for deploying software within that company might need to be refactored. If the company starts to deploy containers in production, and managing those containers using Kubernetes, the company will also want to have a testing pipeline that emulates the production environment using containers and Kubernetes.

Sheroy Marker is the head of technology at ThoughtWorks products, where he works on GoCD, a continuous delivery tool. Sheroy joins the show to talk about how Kubernetes affects continuous delivery workflows, and the process of building out Kubernetes integrations for GoCD.

We also discussed the landscape of continuous delivery tools–why there are so many continuous delivery tools, and the question of how to choose a continuous delivery product if you are implementing CD. Continuous delivery tooling is in some ways like the space of monitoring, logging, and analytics–there are lots of successful products in the market. Full disclosure: ThoughtWorks and GoCD are sponsors of Software Engineering Daily.

", + "Episodes Title": "Kubernetes Continuous Deployment with Sheroy Marker", + "Episodes Uid": "SED4160675484", + "Episodes Audio File": "2ee418bd1fa503381a5ed5f67fa8c547.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ot", + "Episodes ID": "f36d9c32-e328-11ea-91a2-2b74f03f1b0a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_20_BitcoinwithRogerVer.mp3", + "Episodes Pubdate Date": "2018-04-20", + "Episodes Summary": "

Bitcoin and Bitcoin Cash are two cryptocurrencies with similar properties. But the supporters of each of these Bitcoin versions have strongly divergent opinions on the direction of the Bitcoin project. At the center of this debate is the subject of block size.

Bitcoin’s block size determines how many transactions fit into each block that is mined. A larger block size leads to faster transactions and lower fees, but creates higher demands on mining hardware. A smaller block size leads to a slower on-chain network and higher fees, but allows the full nodes on the network to be run on low performance hardware like Raspberry Pi.

Bitcoin Cash has a large block size. Bitcoin Core has a smaller block size. Proponents of the smaller block size argue that Bitcoin’s scaling can be achieved by the off-chain “lightning network” solution.

Roger Ver is a Bitcoin entrepreneur and investor. Since he discovered the currency, he has been buying it and evangelizing it. More recently, Roger has become an ardent supporter of Bitcoin Cash–emphasizing that Bitcoin Cash is Bitcoin.

In this episode, Roger describes his economic ideology, and explains why Bitcoin is so important to him. We explore how vested interests can shape the narrative and the direction of Bitcoin, and talk about the future of how corporations, governments, and individuals might be using cryptocurrencies.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Bitcoin Debates with Roger Ver", + "Episodes Uid": "SED7237839745", + "Episodes Audio File": "41bc7e23c206cb024af00484434d33e3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ee", + "Episodes ID": "ef33aec2-e328-11ea-91a2-538eb474129e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_28_AdFraudCraigSilverman.mp3", + "Episodes Pubdate Date": "2019-02-28", + "Episodes Summary": "

Advertising fraud steals billions of dollars every year.

BuzzFeed reporter Craig Silverman reports on advertising fraud and its impact on the Internet. In one investigation, Craig uncovered a mobile advertising fraud scheme in which four people stole millions of dollars (perhaps as much as $75 million or even $750 million) by serving advertisements to automated users on mobile apps.

The scheme worked as follows:

This scheme was easy to pull off. It did not require much sophistication in terms of engineering or business skills. If a group of four people can generate tens of millions of dollars, how much ill-gotten capital is being generated by large corporations that are deeply involved in the advertising market?

Craig’s article went viral, and he has followed it up with other pieces about ad networks, fraud investigations by Google, and the potential for mobile apps to be used for large scale surveillance of Americans by the Chinese.

Craig is the most dedicated reporter covering advertising fraud today. His work is invaluable because he is asking difficult questions about the economics of our Internet. As we discuss in the episode, there is currently no effective automated means of detecting a bot from a human on the internet.

We have also discussed this in detail on previous episodes about ad fraud, the advertising industry, advertising analytics, and the techniques of ad fraud.

Ad fraud is not the fault of any one party. It is an emergent result of the way that our Internet is set up. It is as hard to imagine a world without advertising fraud as it is to imagine a world without email spam.

", + "Episodes Title": "Ad Fraud Economics with Craig Silverman", + "Episodes Uid": "SED9118486348", + "Episodes Audio File": "0b7f4c769d4b93047c36ea32bf1f283b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yb", + "Episodes ID": "f7056316-e328-11ea-91a2-a3298274a344", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/VijayPandeQuantum.mp3", + "Episodes Pubdate Date": "2017-08-03", + "Episodes Summary": "

Quantum computing is based on the system of quantum mechanics. In quantum computing, we perform operations over qubits instead of bits. A qubit is a vector, which can take on many more values than 0 or 1. The technology used to implement quantum computers is advancing such that it has its own Moore’s Law, but it can also leverage the classical advancements of Moore’s Law.

If classical computing advances at the exponential pace of 2^n, quantum computing advances at the pace of 2^2^n.

Quantum computing will advance technology in ways that will take us by surprise. If things feel like they are moving fast now, just wait until developers have access to quantum processing units. Machine learning, simulated chemical synthesis, and NP-complete problems are ripe for quantum computers.

Vijay Pande is a partner at Andreessen Horowitz and a board member at Rigetti Computing, a quantum computer company. In this episode, we explored what software engineers today need to know about quantum computers and some of the application domains that developers will be working on as quantum computers become available.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Quantum Computing with Vijay Pande", + "Episodes Uid": "SED8246877278", + "Episodes Audio File": "b202c3bea60004e79e8a365aec2414b6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "55q", + "Episodes ID": "eff05c98-e328-11ea-91a2-23f3187ab439", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_03_Ubiquity6.mp3", + "Episodes Pubdate Date": "2019-01-03", + "Episodes Summary": "

Augmented reality glasses will let us walk through a world where the digital blends together with the physical. 3-D objects will be rendered and superimposed onto our field of vision, creating an environment for people to build applications we can hardly dream of today.

These augmented reality glasses are probably three to five years away from being ready for consumer use. But developers are already building augmented reality applications for smartphones using Apple ARKit and Android ARCore. These augmented reality toolkits use powerful smartphone processors and computer vision to give developers simple primitives for placing and manipulating 3-D objects.

Most of these AR applications are made for a single phone, and AR is useful for a single phone–for example, you could hold your phone up in front of an empty room, and see on your phone how it would look if you had an IKEA couch sitting in the middle of that room.

But shared augmented reality experiences are much more exciting.

Shared augmented reality can allow us to play a game of virtual basketball, both controlling the game that is synchronized between us. Shared AR would let me go to a restaurant, and create a virtual billboard in front of the restaurant that only you could see when you walked up to the restaurant and held your phone in front of you.

Ubiquity6 is a company with the goal of enabling shared AR experiences. Ankit Kumar is the co-founder and CTO of Ubiquity6, and he joins the show to explain why building shared AR is a challenging technical problem. It requires building a digital model of the real world, and mapping that model to coordinates in space, so that users can reliably persist augmented reality objects that each other can see.

We discuss computer vision, digital mapping, the increasing power of phone processors, and the potential of shared AR.

", + "Episodes Title": "Ubiquity6: Augmented Reality Platform with Ankit Kumar", + "Episodes Uid": "SED7716665022", + "Episodes Audio File": "be8b4f4c53ca8e97bd54bcb9e0eeb7c3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2hz", + "Episodes ID": "06017044-e329-11ea-91a2-cf226ba1decd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/data-warehousing_edited.mp3", + "Episodes Pubdate Date": "2017-02-27", + "Episodes Summary": "

In the mid 90s, data warehousing might have meant “using an Oracle database.” Today, it means a wide variety of things. You could be stitching together a big data pipeline using Kafka, Hadoop, and Spark. You could be using managed tools like BigQuery from Google.

How did we get from the simple days of Oracle databases to the wealth of options available today? Mark Rittman writes and podcasts about data engineering and data warehousing on his site Drill to Detail. Today, we explore the past, present, and future of data warehousing and touch on many of the trends that have been explored in recent episodes of Software Engineering Daily.

Google BigQuery, and Why Big Data is About to Have Its Gmail Moment

", + "Episodes Title": "Data Warehousing with Mark Rittman", + "Episodes Uid": "SED6412951439", + "Episodes Audio File": "296cf1b6ee616327191b93321b8dc6e2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3pn", + "Episodes ID": "f33ff6ce-e328-11ea-91a2-4b2a46533802", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_02_BuildingDatadog.mp3", + "Episodes Pubdate Date": "2018-05-02", + "Episodes Summary": "

Alexis Le-Quoc started Datadog in 2010, after living through the Internet boom and bust cycle of the late 90s and early 2000s. In 2010, cloud was just starting to become popular. There was a gap in the market for infrastructure monitoring tools, which Alexis helped fill with the first version of Datadog.

Since 2010, the number of different cloud infrastructure products has proliferated. There were new databases, queueing systems, virtualization and containerization tools. Web 2.0 took off, and thousands of new Internet businesses got started. Many of these businesses used Datadog to monitor their increasingly wide range of infrastructure configurations–and Datadog began to scale.

On today’s show, Alexis tells the story of how Datadog grew from its first product into a variety of tools–infrastructure monitoring, logging, and application performance monitoring. Monitoring is a unique challenge–there is a ton of data, the data is latency sensitive, and the data is operationally important. These engineering constraints provide for a great conversation. Alexis is the CTO of Datadog, and we talked about cloud providers, building a business, infrastructure, and how to scale engineering management. Full disclosure: Datadog is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Building Datadog with Alexis Le-Quoc", + "Episodes Uid": "SED9253455578", + "Episodes Audio File": "f57507a4b22caca76477a9e9ce96da9a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4cy", + "Episodes ID": "f19717bc-e328-11ea-91a2-77ac556ee4ad", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_27_PaaSandDraft.mp3", + "Episodes Pubdate Date": "2018-08-27", + "Episodes Summary": "

Back in 2014, platform-as-a-service was becoming an increasingly popular idea. The idea of PaaS was to sit on top of infrastructure-as-a-service providers like Azure, AWS, or Google Cloud, and simplify some of the complexity of these infrastructure providers. Heroku had built a successful businesses from the idea of platform-as-a-service, and there was a widely held desire in the developer community to have an “open source Heroku.”

One project that was working towards the idea of an open source platform-as-a-service was Deis. Deis made it easier for people to deploy and manage their applications, and it simplified some of the hard parts of container management. When Kubernetes came out, Deis got refactored to use Kubernetes under the hood for container orchestration. Deis was one of the first projects to use Kubernetes as a tool to build a platform-as-a-service, and the team that was working on Deis got very early exposure to the process of building a platform on top of Kubernetes.

Michelle Noorali was one of the engineers on the Deis team. When Deis got acquired by Microsoft, Michelle was working on Helm, a package manager for distributed systems. Helm allows developers to deploy distributed applications on top of Kubernetes more easily. A few examples of distributed applications that can be deployed using Helm are Kafka, Prometheus, and IPFS. One reason Helm is so useful is that distributed systems are notoriously hard to configure and run.

Since joining Microsoft, Michelle has continued to work on Helm. She is also a member of the Kubernetes Steering Committee and the board of the CNCF. Michelle joins the show to talk about her early experiences building PaaS and her perspective on the Kubernetes ecosystem. Full disclosure: Microsoft is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Helm with Michelle Noorali", + "Episodes Uid": "SED3032871801", + "Episodes Audio File": "498bec07c49977c4377a7e7d4249d357.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "27u", + "Episodes ID": "135dd61a-e329-11ea-91a2-8335cb0cc67b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/developer_roles_edited.mp3", + "Episodes Pubdate Date": "2016-10-05", + "Episodes Summary": "

Software teams are traditionally composed of roles such as project manager, developer, QA, and manager. What happens if you throw out all of those titles, hire mostly engineers, and ask them to do whatever they think is best? That is the core idea behind Fred George’s idea of Developer Anarchy.

In today’s episode, David Curry guest hosts an interview with Fred George. They talk about the structure of teams and the idea of developer anarchy. For a great complement to this episode, check out the Software Engineering Radio episode about developer anarchy.

", + "Episodes Title": "Developer Roles with Dave Curry and Fred George", + "Episodes Uid": "SED5383960527", + "Episodes Audio File": "a418062d949e31c06468b833730b0681.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "28z", + "Episodes ID": "126266c2-e329-11ea-91a2-4f3c66bc7a50", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RxJSnetflix_edited.mp3", + "Episodes Pubdate Date": "2016-10-25", + "Episodes Summary": "

Netflix has a highly interactive user interface. As I move my mouse around the page, hovering over titles and inspecting movie descriptions, there is a lot going on under the hood. One component of this UI is RxJS, a library for building reactive JavaScript. Reactive programming uses the observer pattern to create objects that emit streams of events. We can compose these streams together to create elegant abstractions.

Reactive programming may seem confusing at first, but it can simplify certain patterns that may be hard to describe with imperative programming. Ben Lesh, a senior software engineer at Netflix, joins the show to explain why reactive programming is useful, and how RxJS is used at Netflix.

", + "Episodes Title": "Reactive JavaScript with Ben Lesh", + "Episodes Uid": "SED1365181672", + "Episodes Audio File": "33c0b04c64162018465f15edbcba7dd4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "53p", + "Episodes ID": "f02cef78-e328-11ea-91a2-b37b00785b51", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_13_Plaid.mp3", + "Episodes Pubdate Date": "2018-12-13", + "Episodes Summary": "

A bank account is a platform for apps to be built on top of.

If that sounds like a weird idea, think about the features of a bank account. Most users only have a single bank account, making it a tool for identity and authentication. The series of transactions in a bank account provides a data set that can be used for analyzing payment history and issuing loans, or insurance.

But there are difficulties to building a platform on top of banking. There are thousands of different banks. If you want to build an application that integrates with a user’s bank, you need to be able to integrate with any bank that the user might use–whether it’s Bank of America, Wells Fargo, or Chase.

Plaid is a company that builds APIs for users to connect to banks. Applications such as Venmo, Betterment, and Coinbase use Plaid to connect with the bank accounts of their users. Jean-Denis Greze joins the show to explain how applications use Plaid, and how Plaid has scaled its infrastructure to handle a high volume of requests. He also discusses the potential of banking as a platform, and the strategy for expanding the APIs that Plaid can offer to developers.

Fintech Daily is a new podcast from Software Engineering Daily covering payments, cryptocurrencies, trading, and the intersection of finance and technology. We are looking for volunteer hosts for Fintech Daily, and if you are interested in working with us to conduct interviews, send an email to host@fintechdaily.co. You can find the podcast on iTunes, Google, and everywhere else, and if you are interested in hosting, don’t hesitate to reach out.

", + "Episodes Title": "Plaid: Banking API Platform with Jean-Denis Greze", + "Episodes Uid": "SED5425469850", + "Episodes Audio File": "811141e1106a0165cd40a09063ff8daa.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 602, + "Episodes ID": "ecf8bf9e-e328-11ea-91a2-2789a32de792", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_31_TechPrimers.mp3", + "Episodes Pubdate Date": "2019-07-31", + "Episodes Summary": "

Videos play a key role in the continuing education of a software engineer. Video can capture many different types of content that is useful for engineers: conference talks, tutorial videos, and podcast-style interviews are all popular formats of online video.

YouTube has become the predominant source for video content about software engineering. The open nature of YouTube’s format allows for a tremendous range of content. No matter what your preference is for how you like to learn and be entertained, YouTube has something for you.

TechPrimers is a media channel that is dedicated to sharing technical knowledge in the form of videos, GitHub repositories, and a thriving community. TechPrimers has over 300 videos on YouTube, and more than 48,000 subscribers who regularly watch content about subjects like AWS, Spring, and Kubernetes.

TechPrimers was founded by Ajay Kumar, a software engineer and vice president at JP Morgan. Ajay has been in the software industry for fifteen years, and has been working in enterprise banking systems for seven years. He has deep experience in modern technologies and engineering practices.

Ajay joins the show to discuss the modern world of software engineering, and his experience building a media platform. He also talks about the technology culture of India. Ajay is based in Bengalaru, and it was exciting to learn how much our different societies have in common thanks to technology. Ajay also had me on his YouTube channel for an interview, which was a lot of fun.

", + "Episodes Title": "TechPrimers: Software Engineering YouTube with Ajay Kumar", + "Episodes Uid": "SED1853138037", + "Episodes Audio File": "b554a35a793ce4004e74ae533a835b6d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4t2", + "Episodes ID": "f0d4321a-e328-11ea-91a2-539e23ad7aae", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_25_Flogo.mp3", + "Episodes Pubdate Date": "2018-10-25", + "Episodes Summary": "

A smart security camera takes in a high volume of video images and processes those images using a set of machine learning models. Those models can be used to identify interesting snippets of movement throughout the day, and decide which of those snippets to keep. Some of the video snippets might contain movement of birds–but other video snippets might contain footage of intruders.

As the video stream is processed on the smart security camera, and machine learning models are used to classify the entities in the video stream, some of the data gets thrown out as useless. Some of the data gets sent to the cloud for additional processing. Some of the data might trigger an alert that there is an intruder on the premises. Each piece of video data is an “event”. These events are processed and acted upon.

Modern applications are highly interactive, and have lots of “events”. Other examples of event data streams are website traffic data, self-driving car data, time-series logging data, and video game session data. Building applications that respond to these high volumes of events requires us to program triggers to react to data streams, actions to take in response to the data streams, and workflows to orchestrate what the overall picture of our application is doing as the application is consuming this large data stream.

Flogo is an event-driven ecosystem for building applications around streams of events. Leon Stigter and Matt Ellis work on Flogo at TIBCO, and they join the show to discuss event-driven application development and their work on Flogo. They also talk about the constraints of machine learning applications at the edge, and how event processing systems like Flogo can be used to handle large data streams on edge devices.

", + "Episodes Title": "Flogo: Event-Driven Ecosystem with Leon Stigter and Matt Ellis", + "Episodes Uid": "SED7620405749", + "Episodes Audio File": "0f9b218977681106faf088e7a5ff1398.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "49o", + "Episodes ID": "f1fb632a-e328-11ea-91a2-1fc7dc58ef42", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_02_TokenProtocols.mp3", + "Episodes Pubdate Date": "2018-08-02", + "Episodes Summary": "

A token is a unit of virtual currency. Most tokens are built on a blockchain-based cryptocurrency platform, such as Ethereum. Building on top of a platform like Ethereum allows these tokens to form their own financial ecosystem while leveraging the scale of an existing currency.

Tokens became highly popular in early 2018, with the boom in ICOs–initial coin offerings. Many of these coins offer a value proposition of a “utility token.” The idea of a utility token is that the token is necessary to transact in a particular ecosystem. If Amazon were to require you to convert US dollars to Amazon coins in order to buy items on Amazon, the Amazon coin would be a “utility token.” There are many different kinds of utility token schemes, and time will tell if this model makes sense for the cryptocurrency investment landscape.

Another type of token is the “security token,” in which a token represents a share in an organization. This token type is more like a stock, or bond, or certificate of ownership of a financial instrument. These types of tokens also have their share of criticism. If I start a company, most of my assets are not represented on a blockchain–the assets are things like hiring contracts, intellectual property, real estate, etc. The legal ownership of these assets is settled by a complicated legal system which has no notion of a blockchain. It’s unclear how the claims of a security token today would be enforced–or why a security token is presently a better option for raising capital than traditional equity or debt instruments.

Felipe Pereira is the author of “On the immaturity of tokenized value capture mechanisms,” a Medium article in which he documents different types of token systems, including several flavors of utility tokens and security tokens. He’s also the co-founder at a company called Paratii. He joins the show to discuss the present viability of token-based systems–and what blockchains have actually proven to be useful for today.

", + "Episodes Title": "Token Types with Felipe Pereira", + "Episodes Uid": "SED3211544449", + "Episodes Audio File": "a6759b9ef2cb5c13559ee802dcb01773.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5wk", + "Episodes ID": "ed585d28-e328-11ea-91a2-9badd78e5ddd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_09_IsraelTechLiorKanfi.mp3", + "Episodes Pubdate Date": "2019-07-09", + "Episodes Summary": "

Creating a software company has never been easier. Software engineers are increasingly seeing entrepreneurship as a viable career path. But the path to being an independent software developer is not always clear. 

Most engineers spend some of their career working at a software company. Even an engineer who intends to build a company someday can thrive within the right environment.

Lior Kanfi is a software engineer and the founder of Tikal, a company he started at the height of the dot com bubble in 1999. His initial vision for the company was to build a product around managing knowledge and people within a company. 

When the dot com bubble burst in the year 2000, it became much harder to run a product-focused business. Companies were not buying lots of experimental software, and investors were not aggressively funding new software companies. After the market collapsed, Lior shifted Tikal from a product-focused company into consulting, in order to have a more reliable income stream.

Today, Tikal is a successful software consultancy based in Israel and the Bay Area. Lior describes the engineers within Tikal as “free radical” software developers: independent people who want to learn about new technologies and build experience interacting with clients.

Lior joins the show to talk about his 20 year journey building Tikal and the differences between engineers in the Bay Area and those in Israel. Lior also hosted the Full Stack Tech Radar Day in Tel Aviv, which was a great conference I attended.

", + "Episodes Title": "Software Free Radicals with Lior Kanfi", + "Episodes Uid": "SED1800721262", + "Episodes Audio File": "094835da2533476e972c847214ba2d7b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ox", + "Episodes ID": "f3604398-e328-11ea-91a2-776d77b82921", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_24_NATSMessageBroker.mp3", + "Episodes Pubdate Date": "2018-04-24", + "Episodes Summary": "

A message broker is an architectural component that sends messages between different nodes in a distributed system.

Message brokers are useful because the sender of a message does not always know who might want to receive that message. Message brokers can be used to implement the “publish/subscribe” pattern, and by centralizing the message workloads within the pub/sub system, it lets system operators scale the performance of the messaging infrastructure by simply scaling that pub/sub system.

Derek Collison has worked on messaging infrastructure for 25 years. He started at TIBCO, then spent time at Google and VMWare. When he was at VMWare, he architected the open source platform Cloud Foundry. While working on Cloud Foundry, Derek developed NATS, a messaging control plane.

Since that time, Derek has started two companies–Apcera and Synadia Communications. In our conversation, Derek and I discussed the history of message brokers, how NATS compares to Kafka, and his ideas for how NATS could scale in the future to become something much more than a centralized message bus.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "NATS Messaging with Derek Collison", + "Episodes Uid": "SED4151667174", + "Episodes Audio File": "68043c85bffa447fd38d6ec826b3b783.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5u5", + "Episodes ID": "ed9dc214-e328-11ea-91a2-2fcce33e2f1d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_19_InfrastructureWarswithShengLiang.mp3", + "Episodes Pubdate Date": "2019-06-19", + "Episodes Summary": "

Sheng Liang was the lead developer on the original Java Virtual Machine. Today he works as the CEO of Rancher Labs, a company building a platform on top of Kubernetes. Sheng joins the show to discuss his experiences in the technology industry.

The container orchestration wars had many victims. The competing standards for how an enterprise should manage its numerous containers caused several companies to go down a path where they were building infrastructure which eventually had to be replaced.

As Sheng discusses in today’s episode, the container orchestration wars almost killed his company. Rancher was originally built on top of a different container orchestrator, and the migration to Kubernetes required a massive rewrite of the Rancher platform.

The container orchestration wars were not the first technology battle that Sheng has seen in his career–and it won’t be his last. In today’s show, we discuss the nature of technology wars. Are they necessary? How can a software company minimize the damage caused by a war between competing standards?

Sheng was an excellent guest and we didn’t cover nearly as many subjects as I wanted to, so we will have to do another show in the future!

", + "Episodes Title": "Infrastructure Wars with Sheng Liang", + "Episodes Uid": "SED7829071391", + "Episodes Audio File": "6ad80eee18ce3ef8c4a11ab472cb2fdc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "49n", + "Episodes ID": "f205f77c-e328-11ea-91a2-e7b6d8d86a06", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_31_JailbreakingAppleWatch.mp3", + "Episodes Pubdate Date": "2018-07-31", + "Episodes Summary": "

Apple operating systems are closed source. This closed source nature gives Apple an extremely successful business model–and a very different software developer ecosystem than Linux-based systems. Since Linux is open source, the information on how to manipulate the system at a low level is very public.

The lack of information about low-level programming in Apple operating systems has led to a large community of “jailbreaking”–where people try to reverse engineer how the closed source systems function. In today’s episode, Max Bazaliy joins the show to describe how he reverse engineered an Apple Watch. It’s a complex security challenge to jailbreak an Apple Watch, as he describes in detail. Max is a security researcher at Lookout, a mobile security company.

", + "Episodes Title": "Jailbreaking Apple Watch with Max Bazaliy", + "Episodes Uid": "SED1920278233", + "Episodes Audio File": "f04ae7a8cda01464aeeff431cffd40de.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5u4", + "Episodes ID": "eda28a2e-e328-11ea-91a2-97c775021b40", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_18_OperatorPattern.mp3", + "Episodes Pubdate Date": "2019-06-18", + "Episodes Summary": "

Kubernetes has made distributed systems easier to deploy and manage. As Kubernetes has become reliable, engineers have started to look for higher level abstractions we can define on top of Kubernetes.

An operator is a method of packaging, deploying, and managing a Kubernetes application.

Operators are useful for spinning up distributed systems such as Kafka, Redis, or MongoDB. These data systems are complicated, stateful applications with lots of failure domains. The operator framework enables a developer to deploy one of these complicated applications with less fear of the system crashing, or entering an erroneous state.

Rob Szumski is an engineer at Red Hat. He joins the show to discuss Kubernetes, the operator pattern, and his time at CoreOS, which was acquired by Red Hat.

", + "Episodes Title": "Kubernetes Operators with Rob Szumski", + "Episodes Uid": "SED9648331733", + "Episodes Audio File": "8bccd3db4635b75901ddfbbea2605b97.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "41m", + "Episodes ID": "f2842cdc-e328-11ea-91a2-83d9c50704e3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_23_CrocodileBrowser.mp3", + "Episodes Pubdate Date": "2018-06-23", + "Episodes Summary": "

Crocodile Browser is a fast browser built by Osine and Anesi Ikhianosime, a pair of brothers from Nigeria. I interviewed them 3 years ago, and in this episode I caught up with Osine to learn what he and his brother have been working on since then.

Osine and Anesi have become friends of mine since we had a conversation several years ago. I met Osine for the first time at the Facebook F8 conference last year, and it was one of the first times I had met someone from another continent on the Internet, then got to hang out with them in person.

There were some issues with network connectivity, so I decided to release this show on the weekend with no ads.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Browser Building with Osine Ikhianosime", + "Episodes Uid": "SED5094963379", + "Episodes Audio File": "9241b859acc0ef54963ea25e1bd26290.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32p", + "Episodes ID": "f651446c-e328-11ea-91a2-8bb19ee5d948", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/PeriscopeData.mp3", + "Episodes Pubdate Date": "2017-09-26", + "Episodes Summary": "

A dashboard is a data visualization that aggregates metrics in a way that we can quickly understand. In a modern software company, everyone uses dashboards–from salespeople to DevOps to HR.

Each dashboard represents a query that must be updated frequently, so that anyone looking at it is getting up-to-date information. The data set being queried might be getting updated quickly in the case of time series or log data. Some queries require joins between disparate data sources.

How do you keep dashboards accurate? How do you keep query latency down?

Tom O’Neill is the CTO of Periscope Data, a company that makes popular dashboarding tools. In this episode, Tom explains the data engineering that underlies Periscope data. We explore topics such as caching, columnar data, and Redshift.

The iOS app is the first project to come out of the Software Engineering Daily Open Source Project. There are more projects on the way, and we are looking for contributors–if you want to help build a better SE Daily experience, check out github.com/softwareengineeringdaily. We are working on an Android app, the iOS app, a recommendation system, and a web frontend. Help us build a new way to consume software engineering content at github.com/softwareengineeringdaily.

", + "Episodes Title": "Dashboarding and Query Latency with Tom O’Neill", + "Episodes Uid": "SED8894960651", + "Episodes Audio File": "ab11d33c9de20748ec3b6c98682eb72c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "wh", + "Episodes ID": "2daf751e-e329-11ea-91a2-63f972a7c81f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Elm_Edited.mp3", + "Episodes Pubdate Date": "2015-11-03", + "Episodes Summary": "

Elm is a functional programming language for web browsers.

Richard Feldman and Srinivas Rao are front­-end developers who work with Elm at NoRedInk.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Elm with Richard Feldman and Srinivas Rao", + "Episodes Uid": "SED9776332480", + "Episodes Audio File": "169ddcbcc5dbdf67af2b1d2989f48157.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "58c", + "Episodes ID": "efca750a-e328-11ea-91a2-57374166589b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_15_NotebooksAtNetflix.mp3", + "Episodes Pubdate Date": "2019-01-15", + "Episodes Summary": "

Netflix has petabytes of data and thousands of workloads running across that data every day. These workloads generate movie recommendations for users, create dashboards for data analysts to study, and reshape data in ETL jobs, to make it more accessible across the organization.

Over the last ten years, data engineering has become a key component of what makes Netflix successful. There are many different engineering roles who interact with the data infrastructure–including data analyst, machine learning scientist, analytics engineer, and software engineer.

Data engineering at Netflix has come a long way from the days of Hadoop MapReduce jobs running nightly, and generating reports of the most popular movies.

As data engineering and data science has grown, the tooling has expanded. The people in different data roles at Netflix might use Apache Spark, Presto, Python, Scala, SQL, and many other applications to study data–but in recent years, there is one tool that has stood out for its ability to be distinctly useful: Jupyter Notebooks.

A Jupyter Notebook lets users create and share documents that contain live code, visualizations, documentation, and many other types of components. In some ways, it is like a shareable IDE, that allows other people to see how you are working with your code and why you are making certain decisions. It is also a tool for building interactive, user-friendly applications–you can embed videos and images in a Jupyter notebook.

A Jupyter Notebook stores both the code and the results together in one place. By combining code with results in one document, you can have context around why a certain result came out the way it did.

Matthew Seal is a senior software engineer at Netflix, where he builds infrastructure and internal tools around Jupyter Notebooks. He joins the show to explain what problems Jupyter Notebooks solve for Netflix, and why they have quickly grown in popularity within the company.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Notebooks at Netflix with Matthew Seal", + "Episodes Uid": "SED4404829177", + "Episodes Audio File": "e033bc20b4ad1e4cb38a778f6eaad3f6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3cu", + "Episodes ID": "f4fbec20-e328-11ea-91a2-bb987619666e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SpringData.mp3", + "Episodes Pubdate Date": "2018-01-04", + "Episodes Summary": "

In the 1980s and the 1990s, most applications used only a relational database for their data management. In the early 2000s, software projects started to use an ever increasing number of data sources. MongoDB popularized the document database, which allows storage of objects that do not have a consistent schema.

The Hadoop distributed file system enabled the redundant storage and efficient querying of high volumes of data that are spread out across multiple commodity disks. The Cassandra Database is a hybrid between key-value storage and column-oriented storage.

The benefit of these different data systems is that you can choose a system that gives you the read and write performance that you need. The downside is that each of these databases has different querying semantics. If you’re a developer trying to access data from your application, you often need to know how to access that data from the specific data source and whether that data needs to be queried with SQL, or with the document style query, or with a MapReduce job.

Spring Data is a project to standardize the programming model for data access within Spring. The vision for the project is to give Spring developers a consistent way to access their data from any database, or retaining the performance characteristics of those databases.

Spring is a Java framework for writing web applications, but this conversation is useful even for people who are not building these Spring applications. Whatever application you’re building, you are probably pulling from multiple data sources. The question of how to abstract away the complexity of those multiple data sources is also being tackled by projects such as GraphQL and Falcor.

John Blum is a staff engineer who works on the Spring Data Project at Pivotal. He joins the show to discuss how to design a data access layer. We discussed the API between a database and the Spring Data layer and also talked about reactive programming. Reactive programming allows the application layer to respond to changes in the underlying data layer.

I interviewed John at SpringOne Platform, which is a conference that is organized by Pivotal, who full disclosure is a sponsor of Software Engineering Daily. This week’s episodes are all conversations from that conference.

If there’s a conference that you think I should attend and do some coverage at, please let me know. Whether you like this format or not, I would love to get your feedback. We have some big developments coming for Software Engineering Daily in 2018, and we want to have a closer dialogue with the listeners. Please send me an e-mail jeff@softwareengineeringdaily.com, let me know what’s up. Or join our Slack channel.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Spring Data with John Blum", + "Episodes Uid": "SED4925962423", + "Episodes Audio File": "29ee3eb4bf26b6c32e2da08d2841469e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5wi", + "Episodes ID": "ed663a42-e328-11ea-91a2-e3ac36ae5a64", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_05_ListenNotes.mp3", + "Episodes Pubdate Date": "2019-07-05", + "Episodes Summary": "

ListenNotes allows users to find podcasts by categories, popularity, and search queries. ListenNotes is not a podcast client that you download onto your phone, but it allows users to build playlists. These playlists are automatically published to an RSS feed, so that users can curate a playlist on desktop and subscribe to that playlist from any client.

Podcasts are growing in popularity. There are more podcasts than ever before, and a podcast search engine needs to refresh its index regularly enough to capture the updates to the podcast universe. 

A podcast search engine needs to decide what to index. There are many potential fields to choose from within a podcast: the podcast title, the description, the audio transcription, and other metadata–should all of these factor into the results of a search engine?

Wenbin Fang is the founder of ListenNotes, and the engineer who has built most of the application. He joins the show to talk about the world of podcasting and his work on ListenNotes, including the business model. Today, ListenNotes makes its money from advertisements and API requests–there is a growing market for applications that want an API for querying the ListenNotes backend.

", + "Episodes Title": "ListenNotes: Podcast Search Engine with Wenbin Fang", + "Episodes Uid": "SED1536837705", + "Episodes Audio File": "6e3aef293a25a28ac6112cacd9c4e9f0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "41l", + "Episodes ID": "f289339e-e328-11ea-91a2-ab6be7998a0e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_22_Pex.mp3", + "Episodes Pubdate Date": "2018-06-22", + "Episodes Summary": "

Searching through all of the videos on the Internet is not a simple problem.

In order to search through all the videos, you need to build a search index. In order to build a search index, you need to build a web crawler. Video files are large. To store all of the actual video files would cost far too much money. In order to build an index in a cost-efficient manner, you need to have a way of storing information about a video without storing the entire video itself.

You might be thinking “hasn’t Google already solved video search? Why are we even talking about this?” Google has solved some aspects of video search–but a different set of challenges is being tackled by a video search company called Pex.

In order to explain what Pex is building, we should first explain the problem set they are trying to tackle.

Videos across the internet are consumed on a variety of platforms such as YouTube, Instagram, Facebook, and Vimeo. These videos are sliced up, bootlegged, and repurposed from one platform to another. For content creators who earn their living from their hosted video streams, this can be a nightmare.

Imagine you are a musician, and you make lots of money from music videos. You upload your cool new video to YouTube, and it instantly gets bootlegged by other users and shared across the internet in hundreds of different places. When people watch the stolen versions of your video, you are not getting compensated. If you could locate all of those stolen videos, you could order them to take it down, or claim the video so that you are paid for it.

And here is the engineering problem–how can you find all those re-posted videos? By crawling the web and building a search index for every video on the web.

Rasty Turek is the CEO of Pex, and in this episode he describes how to build a system that crawls the Internet and indexes videos. It’s a large scale engineering challenge, and there are lots of tradeoffs to be made between financial cost, speed, accuracy, and engineering complexity.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Video Search with Rasty Turek", + "Episodes Uid": "SED9890159437", + "Episodes Audio File": "e6a8483c5f2d457ce97e0d1c68af21b5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2gu", + "Episodes ID": "0761f42c-e329-11ea-91a2-db051cb4814e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Envoy.mp3", + "Episodes Pubdate Date": "2017-02-14", + "Episodes Summary": "

Most tech companies are moving toward a highly distributed microservices architecture. In this architecture, services are decoupled from each other and communicate with a common service language, often JSON over HTTP. This provides some standardization, but these companies are finding that more standardization would come in handy.

At the ridesharing company Lyft, every internal service runs a tool called Envoy. Envoy is a service proxy. Whenever a service sends or receives a request, that request goes through Envoy before meeting its destination.

Matt Klein started Envoy, and he joins the show to explain why it is useful to have this layer of standardization between services. He also gives some historical context for why Envoy was so helpful to Lyft.

", + "Episodes Title": "Service Proxying with Matt Klein", + "Episodes Uid": "SED9175296072", + "Episodes Audio File": "8e0cd7e14015a0f2e02984728525d516.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "54z", + "Episodes ID": "f00c8b66-e328-11ea-91a2-8b69cc52998d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Envoy.mp3", + "Episodes Pubdate Date": "2018-12-24", + "Episodes Summary": "

Originally posted on 14 February 2017.

Most tech companies are moving toward a highly distributed microservices architecture. In this architecture, services are decoupled from each other and communicate with a common service language, often JSON over HTTP. This provides some standardization, but these companies are finding that more standardization would come in handy.

At the ridesharing company Lyft, every internal service runs a tool called Envoy. Envoy is a service proxy. Whenever a service sends or receives a request, that request goes through Envoy before meeting its destination.

Matt Klein started Envoy, and he joins the show to explain why it is useful to have this layer of standardization between services. He also gives some historical context for why Envoy was so helpful to Lyft.

", + "Episodes Title": "Service Proxying with Matt Klein Holiday Repeat", + "Episodes Uid": "SED1235583335", + "Episodes Audio File": "8e0cd7e14015a0f2e02984728525d516.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2gp", + "Episodes ID": "07d36648-e329-11ea-91a2-7b395e6e5e50", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DeepLearning.mp3", + "Episodes Pubdate Date": "2017-02-10", + "Episodes Summary": "

Deep learning uses neural networks to identify patterns. Neural networks allow us to sequence “layers” of computing, with each layer using learning algorithms such as unsupervised learning, supervised learning, and reinforcement learning. Deep learning has taken off in the last few years, but it has been around for much longer.

Adam Gibson founded Skymind, the company behind Deeplearning4j. Deeplearning4j is a distributed deep learning library for Scala and Java. It integrates with Hadoop and Spark, and is specifically designed to run in business environments on distributed GPUs and CPUs. Adam joins the show today to discuss the history and future of deep learning.

", + "Episodes Title": "Deep Learning with Adam Gibson", + "Episodes Uid": "SED8468807387", + "Episodes Audio File": "ea5c031cdb4ca29b1c5a3282ffc6477f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24a", + "Episodes ID": "17ae4bdc-e329-11ea-91a2-37d9ef7dbe42", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Odd_Networks_Edited.mp3", + "Episodes Pubdate Date": "2016-08-03", + "Episodes Summary": "

Odd Networks is building a platform for anyone to launch their own over-the-top streaming video service. With Odd Networks, you can deploy your own video channel using a Roku, Amazon Fire TV, Apple TV, and other services.


\nCreating a streaming video service with interoperability between these different platforms presents numerous technical challenges, and today’s guest Kris Walker explains how Odd Networks is addressing those challenges. We discuss the open source projects of Odd Networks, including oddworks, which encompases the SDKs, stores, services, and middleware, and the event bus, called oddcast.Sponsors

", + "Episodes Title": "Odd Networks with Kris Walker", + "Episodes Uid": "SED5746891022", + "Episodes Audio File": "57bb5d2ee26bcdf5dfe91f7b8d729546.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 777, + "Episodes ID": "e95e01e6-e328-11ea-91a2-ffb3d4a6ce1f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_05_12_Bridgecrew.mp3", + "Episodes Pubdate Date": "2020-05-12", + "Episodes Summary": "

Infrastructure-as-code tools are used to define the architecture of software systems. Common infrastructure-as-code tools include Terraform and AWS CloudFormation.  When infrastructure is defined as code, we can use static analysis tools to analyze that code for configuration mistakes, just as we could analyze a programming language with traditional static analysis tools.

When a developer writes a program, that developer might use static analysis to parse a program for common mistakes–memory leaks, potential null pointers, and security holes. The concept of static analysis can be extended to infrastructure as code, allowing for the discovery of higher level problems such as insecure policies across cloud resources.

Guy Eisenkot is an engineer with Bridgecrew, a company that makes static analysis tools for security and compliance. Guy joins the show to talk about cloud security and how static analysis can be used to improve the quality of infrastructure deployments.

", + "Episodes Title": "Static Analysis for Infrastructure with Guy Eisenkot", + "Episodes Uid": "SED6387567105", + "Episodes Audio File": "081f925fc9ee43b6e2e704c0fcf18449.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1tu", + "Episodes ID": "1f75f8ec-e329-11ea-91a2-876aebfd0188", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/bugsnag_Edited.mp3", + "Episodes Pubdate Date": "2016-04-01", + "Episodes Summary": "

Applications can and will crash — it is increasingly important for developers to have visibility into the reasons how and why the crash occurred. James Smith is the guest on the show today, and joins Jeff to discuss why modern applications crash, and how developer products are improving to tighten the gap between QA/support and dev. James is the founder of Bugsnag, an automated crash monitoring system.

", + "Episodes Title": "Application Crash Monitoring with James Smith", + "Episodes Uid": "SED5104579547", + "Episodes Audio File": "d64a3210ffd1561c5e2a153ff9959497.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ah", + "Episodes ID": "e90f1b26-e328-11ea-91a2-47060575c024", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_03_Tecton.mp3", + "Episodes Pubdate Date": "2020-06-03", + "Episodes Summary": "

Machine learning workflows have had a problem for a long time: taking a model from the prototyping step and putting it into production is not an easy task. A data scientist who is developing a model is often working with different tools, or a smaller data set, or different hardware than the environment which that model will be deployed to.

This problem existed at Uber just as it does at many other companies. Models were difficult to release, iterations were complicated, and collaboration between engineers could never reach a point that resembled a harmonious “DevOps”-like workflow. To address these problems, Uber developed an internal system called Michelangelo.

Some of the engineers working on Michelangelo within Uber realized that there was a business opportunity in taking the Michelangelo work and turning it into a product company. Thus, Tecton was born. Tecton is a machine learning platform focused on solving the same problems that existed within Uber. Kevin Stumpf is the CTO at Tecton, and he joins the show to talk about the machine learning problems of Uber, and his current work at Tecton.

", + "Episodes Title": "Tecton: Machine Learning Platform from Uber with Kevin Stumpf", + "Episodes Uid": "SED5630133604", + "Episodes Audio File": "10483f92ec800270c7de29b0e11034b9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6u7", + "Episodes ID": "ea7f5412-e328-11ea-91a2-8f9c358d9ddf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_18_GoandNetworking.mp3", + "Episodes Pubdate Date": "2020-02-18", + "Episodes Summary": "

A cloud provider gives developers access to virtualized server infrastructure. When a developer rents this infrastructure via an API call, a virtual server is instantiated on physical machines. That virtual server needs to be made addressable through the allocation of an IP address to make it reachable from the open Internet. When the virtual server starts to receive too much traffic, that traffic needs to be load balanced with another virtual server.

The backend networking code that runs a cloud provider needs to be fast, secure, and memory-efficient. Languages that fit that description include C++, Rust, and Go. Digital Ocean’s low-level networking code is mostly written in Go.

Sneha Inguva is an engineer with Digital Ocean who has written and spoken about writing networking applications using Go. She joins the show to talk about her work at Digital Ocean, including the implementation of a DHCP server, a network server that assigns IP addresses and other parameters to devices that sit on that network.

", + "Episodes Title": "Go Networking with Sneha Inguva", + "Episodes Uid": "SED2274130319", + "Episodes Audio File": "5d0eee0d0ee2d59744a85545619c9183.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 275, + "Episodes ID": "124f7f9e-e329-11ea-91a2-bf46e91b41ff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/heroku_kafka_edited.mp3", + "Episodes Pubdate Date": "2016-10-25", + "Episodes Summary": "

Kafka is a distributed log for producers and consumers to publish messages to each other. We’ve done many shows about Kafka as a key building block for distributed systems, but we often leave out the discussion of the complexities of setting up Kafka and monitoring it. Kafka deployments can be a complex piece of software to manage.

Tom Crayford is an engineer at Heroku, where he helped engineer the recent Heroku Kafka product, which is a managed version of Apache Kafka. Our conversation explored the use cases of Kafka and how to build Kafka as a cloud service at scale. For more information about Heroku Kafka, check out an upcoming webinar.

Full disclosure: Heroku is a sponsor of Software Engineering Daily. That said, this is a topic I am genuinely interested in–it is often difficult to get cloud providers to talk in detail about how they are architecting their services.

", + "Episodes Title": "Managed Kafka with Tom Crayford", + "Episodes Uid": "SED5243138352", + "Episodes Audio File": "55466fd673e8819249e8bbaceeae8b97.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ec", + "Episodes ID": "eba75416-e328-11ea-91a2-b31db3357607", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_11_Gatsby.mp3", + "Episodes Pubdate Date": "2019-11-11", + "Episodes Summary": "

Frontend software development has become as complex as backend development.

There was a time when frontend web development was simple. There was a small number of JavaScript frameworks and templating systems. Your CSS was simple configuration for the colors on your webpage. Today, there is a giant ecosystem of frontend tools, APIs, and middleware delivering data to the user.

Gatsby is a framework based on React that allows developers to build performant web applications. Gatsby is not easy to explain. In some ways, it is like a compiler for your website. Gatsby pulls in the data that you need to build your website, including CMS data, APIs, and markdown, and then links that information into React components and CSS. This happens on the server, so your user gets served a website that does not require lots of round trips as your website renders.

Kyle Mathews and Sam Bhagwat are the founders of Gatsby, the company that is based around GatsbyJS. They join the show to describe their vision for the framework, and their vision for the company.

", + "Episodes Title": "Gatsby with Kyle Mathews and Sam Bhagwat", + "Episodes Uid": "SED6148943831", + "Episodes Audio File": "cde2925b08e15f79fd668aea0716aadb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "20i", + "Episodes ID": "1b2f70d8-e329-11ea-91a2-27871b81122f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Getify_Edited.mp3", + "Episodes Pubdate Date": "2016-06-13", + "Episodes Summary": "

JavaScript programming usually is done through the use of frameworks, such as ReactJS, AngularJS, and EmberJS. These frameworks abstract away some of the messy details of JavaScript, and simplify web development so that engineers can build products at a faster pace. When we build software using JavaScript frameworks, we are missing out on some of the richness of the JavaScript language itself.


\nKyle Simpson is the author of “You Don’t Know JS”, a series of books that suggests that JavaScript developers should start from the ground up, not from the top down. By learning the basics of JavaScript, a software engineer can learn the timeless fundamentals that will not disappear with the creation of next week’s hottest framework. After exploring the idea of frameworks versus raw JavaScript, Kyle and I discuss asynchronous JavaScript, from concurrency to the observer pattern. Sponsors

", + "Episodes Title": "JavaScript Concurrency with Kyle Simpson", + "Episodes Uid": "SED7523876357", + "Episodes Audio File": "43c2ee42c93ee9086712823ee68ce99e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7gg", + "Episodes ID": "e869921e-e328-11ea-91a2-0b327e4f0644", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_22_SourceGraph.mp3", + "Episodes Pubdate Date": "2020-07-22", + "Episodes Summary": "

A large codebase cannot be searched with naive indexing algorithms. In order to search through a codebase the size of Uber’s it is necessary to build a much more sophisticated indexing system than simple pure text search.

SourceGraph is a system for universal code search. It allows developers to more easily onboard to a new codebase, make large refactors, and perform other tasks. SourceGraph can integrate with source control systems, IDEs, and other tools to fit comfortably into an engineer’s workflow.

Beyang Liu is a co-founder of SourceGraph and he joins the show to talk about how codebases can become large and unwieldy, and the tooling that SourceGraph offers to make these codebases easier to work with.

", + "Episodes Title": "SourceGraph: Code Search and Intelligence with Beyang Liu", + "Episodes Uid": "SED9840228479", + "Episodes Audio File": "d3a23077fbb8370c3a00ddf69da58e57.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6xj", + "Episodes ID": "ea32219c-e328-11ea-91a2-330896a42a93", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_11_CloudInvestingDanel.mp3", + "Episodes Pubdate Date": "2020-03-11", + "Episodes Summary": "

Cloud computing caused a fundamental economic shift in how software is built. Before the cloud, businesses needed to buy physical servers in order to operate. There was an up-front cost that often amounted to tens of thousands of dollars required to pay for these servers. 

Cloud computing changed the up-front capital expense to an ongoing operational expense, with businesses increasingly shifting to Amazon Web Services, Microsoft Azure, and Google Compute Platform. 

Although the initial motivation for moving onto cloud providers might have been decreased cost, over time the cloud providers have developed unique services that make software even easier to build than before. There has also been a proliferation of new software infrastructure companies that have been built on top of the cloud providers, giving rise to new databases, logging companies, and platform-as-a-service products.

Danel Dayan is a venture investor with Battery Ventures and a co-author of the State of the OpenCloud 2019, a report that compiles a wide set of statistics and information on how cloud computing and open source are impacting the software industry. Danel joins the show to talk about his work as an investor, as well as his previous career at Google, where he worked on mergers and acquisitions.

If you want to reach Danel you can email him at ddayan@battery.com or tweet at him via @daneldayan.

", + "Episodes Title": "Cloud Investing with Danel Dayan", + "Episodes Uid": "SED7473404044", + "Episodes Audio File": "7551c88aabfc017109d899cc36607c5e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 162, + "Episodes ID": "277cdbd2-e329-11ea-91a2-a31b05ae7c80", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Triplebyte_Edited.mp3", + "Episodes Pubdate Date": "2015-12-23", + "Episodes Summary": "

Triplebyte is a technical hiring platform that vets engineers using a comprehensive evaluation platform and connects them to companies that are interesting in hiring them. Triplebyte was part of the Y Combinator summer class of 2015.

Ammon Bartram is the Chief Data Officer and cofounder of Triplebyte. Previously, Ammon was lead video developer at Justin.tv and also cofounded SocialCam.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Hiring Engineers with Ammon Bartram", + "Episodes Uid": "SED9791351608", + "Episodes Audio File": "3a53f0054b1cf1e98b89bef83bd056fc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6yp", + "Episodes ID": "ea123c42-e328-11ea-91a2-13a77e7c6370", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_20_ClickUp.mp3", + "Episodes Pubdate Date": "2020-03-20", + "Episodes Summary": "

Over the last fifteen years, there has been a massive increase in the number of new software tools. This is true at the infrastructure layer: there are more databases, more cloud providers, and more open-source projects. And it’s also true at a higher level: there are more APIs, project management systems, and productivity tools.

ClickUp is a project management and productivity system for organizations and individuals. The goal of ClickUp is to create a system that integrates closely with other project management systems, popular SaaS tools, and the Google Suite of docs and spreadsheets. The company was started in 2016, and despite raising zero outside capital, it has grown as rapidly as many venture-backed companies.

Zeb Evans and Alex Yurkowski are the founders of ClickUp. They join the show to talk about their experience building the company. We talk through their process of scaling the infrastructure, and their philosophy of moving fast. This episode has some useful strategic advice for anyone who is looking to take a product to market and iterate quickly–even if that product is bootstrapped. Full disclosure: ClickUp is a sponsor of Software Engineering Daily.

", + "Episodes Title": "ClickUp Engineering with Zeb Evans and Alex Yurkowski", + "Episodes Uid": "SED9427799163", + "Episodes Audio File": "f620404b33fdbda70801a1ca648d30a2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "78n", + "Episodes ID": "e93d437a-e328-11ea-91a2-47180e8a87d9", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_20_Rudderstack.mp3", + "Episodes Pubdate Date": "2020-05-20", + "Episodes Summary": "

Customer data infrastructure is a type of tool for saving analytics and information about your customers. The company that is best known in this category is Segment, a very popular API company. This customer data is used for making all kinds of decisions around product roadmap, pricing, and design.

RudderStack is a company built around open source customer data infrastructure. RudderStack can be self-hosted, allowing users to deploy it to their own servers and manage their data however they please. Soumyadeb Mitra is the creator of RudderStack, and he joins the show to talk about the space of customer data infrastructure, and his own company.

", + "Episodes Title": "RudderStack: Open Source Customer Data Infrastructure with Soumyadeb Mitra", + "Episodes Uid": "SED5442477856", + "Episodes Audio File": "5e9e873584835d6780fbd999618f2230.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1b0", + "Episodes ID": "2508ebde-e329-11ea-91a2-ab21846b8930", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Spark_Edited.mp3", + "Episodes Pubdate Date": "2016-01-21", + "Episodes Summary": "

Apache Spark has skyrocketed in popularity lately, arguably surpassing Hadoop as the hottest big data technology as of late. Even IBM has thrown its weight behind the framework, calling it the “most important new open source project in a decade”. In this episode, Holden joins Software Engineering Daily to discuss why Spark is growing in popularity and how developers can begin learning the framework.

Holden Karau is a principal engineer at IBM working with Apache Spark. She is also an author of Learning Spark, a technical guide for developers new to the data processing framework.

", + "Episodes Title": "Spark in Practice with Holden Karau", + "Episodes Uid": "SED8590790341", + "Episodes Audio File": "9f94db9126e1ce13cd76a11f69763476.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6v4", + "Episodes ID": "ea6cb0be-e328-11ea-91a2-d744fce01f16", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_24_EffxJoeyParsons.mp3", + "Episodes Pubdate Date": "2020-02-24", + "Episodes Summary": "

At Airbnb, infrastructure management is standardized across the organization. Platform engineering teams build tools that allow the other teams throughout the organization to work more effectively. A platform engineering team handles problems such as continuous integration, observability, and service discovery.

Other teams throughout a company use the tools that a platform engineering team builds. For example, there is a team at Airbnb that builds the search and discovery system that is used by customers who are looking for a place to stay. That team does not want to have to worry about how they are deploying, how their service is being logged, and how to scale up. All of that should be taken care of by the platform engineering team.

At a large company like Airbnb, there is so much happening across the infrastructure. Services are being deployed, services are having outages, databases are being resharded. With all of this change occurring, it can be difficult for a team to pinpoint the cause of a service outage. Digging through logs and dashboards is often insufficient.

Joey Parsons is the founder of Effx, a company that is building a platform for observing and managing the changes across the infrastructure. Effx is like a newsfeed for a service. An application instrumented with Effx gives the engineers a single endpoint that they can navigate to for understanding the history of their service.

Joey joins the show to talk about his experience as an infrastructure engineer at Airbnb, and how that experience informs the work of his new company, Effx.

", + "Episodes Title": "Infrastructure Management with Joey Parsons", + "Episodes Uid": "SED6546359421", + "Episodes Audio File": "54d5d1c746660c53548fdb0bce5a79c2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5n3", + "Episodes ID": "ee57045e-e328-11ea-91a2-73eac7016785", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_26_CloudwithEricBrewer.mp3", + "Episodes Pubdate Date": "2019-04-26", + "Episodes Summary": "

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

Google’s strategy for cloud computing is centered around providing open source runtime systems and a high quality developer experience.

Google is highly differentiated in its approach to the cloud. To understand Google’s strategy, it is useful to first set the context for the current competitive environment of cloud providers.

Amazon Web Services (AWS) popularized cloud computing in 2006. AWS was first to market, which has given the company a large competitive advantage over the rest of the industry. It took Google several years to realize how big the public cloud market was, and how good the economics of running a cloud provider could be. Microsoft also realized the opportunity several years after AWS was started.

The multi-year lead that AWS had on getting to market has given the company tremendous leverage. Because AWS is the most widely trusted, accepted default in the market, AWS is able to deepen that relationship more and more over time, despite the fact that the proprietary APIs of AWS create a level of lock-in that bears some resemblance to the lock-in of Microsoft Windows or Oracle’s relational database systems.

The brief history of software gives us examples of what is supposed to happen next.

When a large company is operating a proprietary developer platform, the open source software ecosystem reflexively comes out with an alternative, open source solution that is better than the proprietary system, right? We saw this with the Linux project, which channeled the developer resentment of the proprietary Windows operating system software into the development of the best server operating system to date: Linux.

The difference between Microsoft Windows in the 90s and AWS today is that, for the most part, developers do not resent AWS. AWS keeps its prices low, and embodies a spirit of innovation despite the fact that AWS is partly built around a repeated process of taking open source projects, packaging them up into cloud services, and integrating them closely with other AWS tools, making it harder to move away from AWS.

In its pioneering offerings of managed services, AWS made it easier to set up tools that had previously been impossible for less-experienced developers to operate. Distributed systems became approachable. Companies like Netflix, Lyft, and Heroku were built on the simplified operational model of AWS.

AWS also innovates outside of this business model of repackaging open source projects.

When AWS pioneered the function-as-a-service model, they created an easy way to scale stateless computation. They presented the developer world with an entirely new compute model: event-driven programming, with services communicating to each other via functional glue code running in cheap, transient containers.

There is strong criticism of the event-driven, AWS Lambda-bound “serverless” compute model. And those critics make a valid point: AWS Lambda is a proprietary API.

To build your app around an event-driven architecture glued together with Lambda functions is to lock yourself tightly to Amazon infrastructure. But the critics of this model do not seem to be the ones who are actually locked in. Critics of Amazon’s proprietary strategy tend to be those with a strong incentive to be critical.

Another common criticism of AWS comes from commercial open source companies such as Redis Labs and Elastic, which are vendors of the Redis open source in-memory data system, and the open source Elasticsearch search and retrieval system respectively. These vendors argue that AWS has violated the spirit of open source by repackaging open source software as profitable software and failing to contribute back to the open source ecosystem with commensurate open source contributions.

AWS has repackaged both Redis and Elasticsearch as AWS Elasticache and Amazon Elasticsearch Service respectively.

These vendors frame their relationship to AWS as zero sum, and are turning to licensing changes as their strategy of choice for creating a new defensible moat against AWS. In various Internet forums, the indignant commercial open source software vendors and AWS have both made their cases to the developer community.

If you are a developer who just wants to build your software, these arguments are an unsettling distraction. In addition to worrying about fault tolerance and durability guarantees and cost management, you now have to worry about licensing.

And as you observe these circumstances, with open source vendors accusing cloud providers of improper behavior, you might begin to wonder: what actually are the rules of open source? By what set of commandments are we judging who is good and who is bad?

And who is to judge what is fair or unfair activity by Amazon, which was the first company to prove to all of us just how influential cloud computing could be?

This is the competitive landscape of the cloud circa April 2019, when I attended Google Cloud Next, Google’s annual cloud developer conference.

Throughout the conference, the optimism and playful spirit of Google was present everywhere. There were colorful shapes and cartoonish diagrams that looked like building blocks made for children. In the expo hall, there were food pillars from which free candy and salted snacks could be grabbed all day long.

On one side of the expo hall, a demonstration from IKEA showed how the company was partnering with Google to run its business more like a software company. Stretching across the expo hall in a carpeted distance of multiple football fields, the various vendors showed off their latest wares in a bazaar of multicloud, hybrid cloud, and Kubernetes-compliant sales pitches.

Over the last decade, large enterprises have opened up their wallets more and more, realizing just how valuable cloud infrastructure can be for their businesses. The more they spend, the more efficient their workers become, and the faster their businesses can improve. For modern enterprise, the cloud is the closest thing to magic that we have.

Knowledge workers are becoming unshackled from the painful, slow pace of early technological corporatism. The cloud can empower all of us–and rather than replacing our jobs with machines, the cloud will allow us to better express our humanity within our work.

The twin forces of consumer mobile computing on the client side and cloud computing on the server side are compounding faster than we can measure. Five years ago, a common analogy was to compare the smartphone to a “remote control for your life”. Today the smartphone feels more like a magic wand than a remote control. We can summon tremendous forces from the magical cloud by merely speaking the right command into our wand-like smartphone.

The effects on corporate enterprise operations are exciting to watch. I go to a lot of conferences, and I prefer to walk around the expo hall rather than to go to any sessions. At the expo hall, you see the distance between vendor hype and the realities of the enterprise. From my vantage point, that distance gets shorter every year: enterprises truly are adopting DevOps, continuous delivery, machine learning, and data platforms.

From insurance companies to banks to farming companies to furniture outlets: the “digital transformation” is actually happening. This is great for consumers, and great for employees at the large corporations that are being digitally transformed.

What is it like to work at a large, 100 year old enterprise that is going through digital transformation? It is certainly much more appealing than it was a decade ago.

The servile, bureaucratic, rent-seeking hierarchies of the 80s, 90s, and early 2000s are slowly being refurbished into enterprises where bottoms-up innovation, individualism, and artistic energy are assets rather than liabilities. We are moving out of the age of boring cubicle industrialism towards a vision in which work is truly creative and fulfilling for every member of the corporation.

And Google evangelizes this ideal stronger than any other company in the world.

With its tremendous cash flows from its advertising business, Google reinvests heavily into its employee base. Many employees at Google have worked there for a decade and show no intention of leaving, having found a job, but more importantly a culture and an engineering environment that is unrivaled.

Speaking subjectively: my sense is that Google’s internal engineering tools are the best in the world. For many years, Google has been the strongest magnet for talent in the realm of Internet infrastructure and machine learning. In terms of sophistication, the rest of the software industry has been playing catch-up to Google since the days of the MapReduce paper.

Speaking of the MapReduce paper: even in those early days, Google was willing to share its findings with the outside world. Google was tactical about which innovations it would open up about, but it does seem that Google has truly tried to embody some of the publishing philosophies of academia.

Google’s early investments in an academic-like environment have borne considerable fruit. The curiosity and cross-institutional collaboration enabled by Google’s willingness to speak openly about its research have made Google a refuge for academics, including today’s guest Eric Brewer.

Beyond its considerable contributions as a publisher of computer science theory, Google has also become the model software engineering practitioner.

Google has scaled its internal tools to make its thousands of developers highly productive. Given its success with its internal developers, it should come as no surprise that Google has strong opinions about the best way to build services for external developers.

I have often wondered what it is actually like to work within Google as an engineer. I have worked at Amazon, and seen their internal tooling. At Amazon, the level of tooling gave engineers tremendous leverage. But from talking to more experienced engineers, my sense is that nobody holds a candle to the internal tools of Google.

Drishti CTO Krish Chaudhury was a recent guest on this podcast. He spent nearly a decade at Google working on computer vision projects. Today he is building his own computer vision company. When I asked him if we yet had “Google Infrastructure for Everyone”, he sighed deeply and wistfully before answering with an unequivocal “no”.

This hints at what Google wants to do with its cloud. Google does not think of Google Cloud as commodity cloud computing services. The vision for Google Cloud is to be the premier cloud, the deluxe set of services that provides “Google Infrastructure For Everyone”.

This is a moonshot, and in order to accomplish it, Google will need to forego certain short term opportunities for cash grabs. But it is undoubtedly a more fiscally wise strategy for Google to optimize growth of the 2029 Q3 cloud market rather than that of 2019 Q3.

From a conglomerate standpoint, Google already has a cash cow. Google has won today’s war, and it only makes sense to focus on tomorrow’s.

In Google’s approach to the cloud, we see a cultural distinction between Amazon and Google. The cultures of Amazon and Google are partly deliberate, but partly driven by the nature of their businesses’ respective revenue streams.

Amazon built its e-commerce business in a low-margin, highly competitive environment. Amazon won its customers over through a slow process of building trust. In its delivery of physical goods, Amazon formed close relationships with customers. Amazon would repeatedly listen to these customers and use that feedback to improve their products. This “flywheel” of iterative improvement is the core engine that keeps Amazon improving incrementally.

Amazon also has made far-flung, ambitious investments–but the size and scope of Amazon’s moonshots was constrained for many years by its lack of any singularly large cash cow. Fire Phone notwithstanding, Amazon’s moonshots have often been thrifty asymmetric bets, requiring minimal upfront investment but presenting huge potential payoff.

Google, on the other hand, has been in a much more luxurious financial position for most of its life.

Google has a high margin advertising business that accounts for ~84% of its revenues, subsidizing everything else in Google (and Alphabet). Because it has such a big cash cow in a totally different area of the business, Google can afford to take an extremely long-term approach to its vision for the cloud. For Google, the goal is not to maximize the profit margins of the cloud over the next two years. Google can afford to think of cloud profitability in the increment of decades.

In the business of cloud computing, Google has turned the weakness of being a late mover into a wide set of strengths.

The AWS console presents its users with a sprawling array of possibilities. Google Cloud has a lower surface area. Google is more opinionated about the right way to do things–and it is easier for Google to build in an opinionated fashion because there are fewer legacy customers and edge cases to support. AWS supports the majority of the market, so it is in a position where it must keep those customers happy in order to hold onto its moat.

So what are Google’s strong opinions about the way that a cloud should operate?

Google’s espoused vision is that of the “open cloud”: a cloud environment where organizations could easily move workloads from one cloud provider to another.

If we take the purest, most aspirational interpretation of “open cloud”, the full stack would be open source. Identity and access management systems would be portable as well, and cloud providers would work together to reduce the switching costs between each other, even in cases of data gravity.

As virtuous as the idea of the “open cloud” sounds, it is also strategically convenient for Google. Since it lags behind Amazon and Microsoft in terms of adoption, a gradual shift towards a widely standardized open cloud would theoretically make it easier for Google to recover market share as the cloud market matures.

Whatever Google’s true motives are, the “open cloud” strategy has been tremendously bountiful to the developer community.

By open sourcing Kubernetes and pouring resources into it, Google brought an end to the painful, wasteful container orchestration wars. In its donation of Kubernetes to the Cloud Native Computing Foundation (which it also is a heavy financial donor to), Google created an ostensibly open, positive sum environment for the rivaling cloud providers to congregate productively.

In the area of machine learning, Google open sourced TensorFlow and invested heavily into tutorials, documentation, YouTube videos, and other resources. Google built JavaScript libraries and auditability and visualization tools. Google has marshalled an entire ecosystem around TensorFlow.

Some of Google’s commercial open source efforts have had less favorable results.

The Istio service mesh project seems to have been promoted with the same playbook that Kubernetes and TensorFlow followed, but with a less usable tool. In Istio, we see Google’s expertise in advertising perhaps taken too far.

Why is Istio a problematic case study?

Because, despite the fact that there are multiple open source service mesh products on the market with significant production usage, Istio has managed to make so much noise about itself that it is convincing the market that the battle for service mesh superiority is a foregone conclusion.

From the blog posts, to the KubeCon programming to the expo hall hype, the cloud native developer community has been hammered with the same messaging about service mesh: Istio is the best, don’t bother with the rest.

Perhaps Google is just doing us all a favor with Istio. Maybe it really is the best service mesh, just not for workloads that serve production. Or maybe Google is just ironing out the kinks, and the marketing roadmap happened to proceed at a faster pace than the engineering roadmap. Honestly, I don’t really know.

In any case, I’m not passing judgment on whether Google has done something morally wrong by pushing Istio prematurely. I just think it was strategically unwise. With Istio, Google made it a little too obvious just how much narrative control it has over the public developer market.

Perhaps this narrative control should come as no surprise. Of all the major clouds, Google is the most well-versed in open source. From its contributions to Linux to its maintenance of a complicated Android ecosystem, Google knows how to play its cards in the game of open source diplomacy.

In battle, a classic strategy for competing with a rival that has an advantage is to force that rival onto territory that you are more familiar with. There are many historical cases where a small army was able to defeat a large army due to its ability to maneuver the battle front to a favorable environment.

Through its open cloud strategy, this is exactly what Google is doing. Google is open sourcing the best way that it knows how to build and run infrastructure software. This is happening slowly but steadily. To some extent, the other major providers including Amazon will have no choice but to follow Google into a battleground that was built by Google.

And as developers, we will get to reap all the rewards of this competition. Our infrastructure will become more standardized, more fault tolerant, cheaper, better designed, and easier to use. And who knows, maybe someday we will actually be able to easily move workloads from one cloud to another.

To the extent that I am a software engineering journalist, I feel inclined to scrutinize all of the cloud providers. But to the extent that I am an engineer and a business person, I feel only admiration and love for the cloud providers. Cloud computing has brought the cost of starting an Internet business down to zero.

Cloud computing has opened up my eyes to a world of creative possibilities that knows no boundaries, and for that I will always be a fan of all of the rivaling cloud companies because they all have played a role in creating the current software landscape.

Eric Brewer is a Google Fellow and VP Infrastructure. He is well-known for his work on the CAP theorem, a distributed systems concept that formalized the tradeoffs between consistency, availability, and partition tolerance in a distributed system.

At Google, Eric is as much a strategist and product creator as he is a theoretician. He has worked on database systems such as Spanner, machine learning systems such as TensorFlow, and container orchestration systems such as Kubernetes and GKE.

Eric joins the show to talk about Google’s philosophy as a cloud provider, and how his understanding of distributed systems has evolved since joining the company.

", + "Episodes Title": "Cloud with Eric Brewer", + "Episodes Uid": "SED3749116519", + "Episodes Audio File": "99462812e7650419a1a8947f9f79636c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1av", + "Episodes ID": "25363ad0-e329-11ea-91a2-7b868ba1e8ed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Wiseio_Edited.mp3", + "Episodes Pubdate Date": "2016-01-19", + "Episodes Summary": "

Machine learning is something that many business are starting to tack onto their existing processes. Yet, to add machine learning capabilities after the fact is often a fool’s errand. Joshua argues that machine learning cannot be an afterthought, but rather must be custom developed to suit the specific problem or question that each company is trying to answer. His company, Wise.io, tackles this challenge of helping business build ground up machine learning applications that generate accurate predictions for use in an array of business processes.

Joshua Bloom is the cofounder and CTO of Wise.io. He is also an astrophysicist, and a professor of astronomy at UC Berkeley.

", + "Episodes Title": "Machine Learning for Businesses with Joshua Bloom", + "Episodes Uid": "SED8173170005", + "Episodes Audio File": "6a21056a6e370484a9a0de9daa689a9a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1df", + "Episodes ID": "24373f12-e329-11ea-91a2-f379fe472698", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Devtea_Edited.mp3", + "Episodes Pubdate Date": "2016-02-02", + "Episodes Summary": "

Software engineering combines art, science, and philosophy. On the Developer Tea podcast, Jonathan Cutrell explores how engineers can improve their technical ability as well as their interpersonal skills and mental clarity. On this episode of Software Engineering Daily, Jeff and Jonathan about focus, career development, and software podcasting.

Jonathan Cutrell is the founder and host of Developer Tea. He is also the Director of Technology at Whiteboard.

", + "Episodes Title": "Developer Tea with Jonathan Cutrell", + "Episodes Uid": "SED8028009440", + "Episodes Audio File": "33cf9fc3cc1ef31f6154f4fa8043e15b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6vi", + "Episodes ID": "ea637468-e328-11ea-91a2-9322db01ea9f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_26_ParabolaNoCode.mp3", + "Episodes Pubdate Date": "2020-02-26", + "Episodes Summary": "

Every company has a large number of routine data workflows. These data workflows involve spreadsheets, CSV files, and tedious manual work to be done by a knowledge worker. 

For example, data might need to be taken from Salesforce, filtered for new customers, and piped into Mailchimp. Or perhaps you need to sort all your customers to find only the ones who have spent more than $50.

These data workflows might require some basic knowledge of SQL, or an understanding of how to make an API request. Not everyone knows how to execute these technical commands. A software company can be slowed down due to a shortage of technical analysts who have the necessary programming skills to build these data workflows.

Parabola is a low-code tool for building data workflows. Parabola lets the user drag and drop different components together to build an application without using a programming language. Parabola lowers the technical barrier for knowledge workers who want to build these kinds of data workflows. Alex Yaseen is the CEO of Parabola, and he joins the show to talk about the ideas behind Parabola and his goals with the company. 

parabola.io

parabola.io/careers

Twitter: @alexyaseen

", + "Episodes Title": "Parabola: No-Code Data Workflows with Alex Yaseen", + "Episodes Uid": "SED1943287477", + "Episodes Audio File": "4b58c913684cdef7aa3fa721716e6179.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 721, + "Episodes ID": "e9d177f2-e328-11ea-91a2-03be7396e36d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_09_SnorkelDataEngineering.mp3", + "Episodes Pubdate Date": "2020-04-09", + "Episodes Summary": "

Machine learning models require the use of training data, and that data needs to be labeled. Today, we have high quality data infrastructure tools such as TensorFlow, but we don’t have large high quality data sets. For many applications, the state of the art is to manually label training examples and feed them into the training process.

Snorkel is a system for scaling the creation of labeled training data. In Snorkel, human subject matter experts create labeling functions, and these functions are applied to large quantities of data in order to label it. 

For example, if I want to generate training data about spam emails, I don’t have to hire 1000 email experts to look at emails and determine if they are spam or not. I can hire just a few email experts, and have them define labeling functions that can indicate whether an email is spam. If that doesn’t make sense, don’t worry. We discuss it in more detail in this episode.

Braden Hancock works on Snorkel, and he joins the show to talk about the labeling problems in machine learning, and how Snorkel helps alleviate those problems. We have done many shows on machine learning in the past, which you can find on SoftwareDaily.com. Also, if you are interested in writing about machine learning, we have a new writing feature that you can check out by going to SoftwareDaily.com/write.

", + "Episodes Title": "Snorkel: Training Dataset Management with Braden Hancock", + "Episodes Uid": "SED6596853144", + "Episodes Audio File": "5fe5888c1b00c2c34e0f177eb1326aed.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "19f", + "Episodes ID": "2610673c-e329-11ea-91a2-eb57d5c27677", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Learning_Rails_Edited.mp3", + "Episodes Pubdate Date": "2016-01-11", + "Episodes Summary": "

Michael Hartl is the author of The Ruby on Rails Tutorial, a widely acclaimed guide to learning how to build Ruby on Rails webapps.

", + "Episodes Title": "Learning Rails with Michael Hartl", + "Episodes Uid": "SED6771426076", + "Episodes Audio File": "7a807efd5b119aedc268820bf6e8512f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 755, + "Episodes ID": "e9870f0a-e328-11ea-91a2-5340fda2c9f0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_30_TinaCMS.mp3", + "Episodes Pubdate Date": "2020-04-30", + "Episodes Summary": "

A content management system (CMS) defines how the content on a website is arranged and presented. The most widely used CMS is WordPress, the open source tool that is written in PHP. A large percentage of the web consists of WordPress sites, and WordPress has a huge ecosystem of plugins and templates.

Despite the success of WordPress, the JAMStack represents the future of web development. JAM stands for JavaScript, APIs, and Markup. In contrast to the monolithic WordPress  deployments, a JAMStack site consists of loosely coupled components. And there are numerous options for a CMS in this environment.

TinaCMS is one such option. TinaCMS is an acronym for “Tina Is Not A CMS”, and it is a toolkit for content management. Scott Gallant, Jordan Patterson, and Nolan Phillips work on TinaCMS, and they join the show to explore the topic of content management on the JAMStack.

", + "Episodes Title": "JAMStack Content Management with Scott Gallant, Jordan Patterson, and Nolan Phillips", + "Episodes Uid": "SED7252035511", + "Episodes Audio File": "cd12ddcc6860a28b57f2f1e1bd06453d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "27s", + "Episodes ID": "136c35fc-e329-11ea-91a2-57ed864c1a4d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/PaaS_with_Sinclair_edited.mp3", + "Episodes Pubdate Date": "2016-10-04", + "Episodes Summary": "

Platform as a service can mean different things to different people. The most prominent feature of a PaaS is the ability to abstract away issues that every developer within an organization has to deal with. As an example, developers today don’t need to fear scalability and load balancing issues as much as engineers of the 90’s and early 2000s. We can develop our applications without worrying about the scaling that is going on under the covers.

Sinclair Schuller is the CEO of Apprenda and he joins the show today to discuss what is involved in building a PaaS, particularly one targeted at enterprises. His company was started in 2007, just a few years after AWS got started.

We also talked about the potential Docker Fork, for which Sinclair had useful business and engineering perspectives.

", + "Episodes Title": "Platform as a Service with Sinclair Schuller", + "Episodes Uid": "SED2175152338", + "Episodes Audio File": "c2a2b904ab35d5a1640db6fed2c6e3ce.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1i7", + "Episodes ID": "22f08e92-e329-11ea-91a2-5b122bb2d4c3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/iot_Edited.mp3", + "Episodes Pubdate Date": "2016-02-18", + "Episodes Summary": "

JavaScript is everywhere, on the browser, the server, and now on hardware. Finally–the Internet of Things is upon us — and it is powered by JavaScript. Even if you consider yourself a web developer, and you have no interest in “maker” culture, keep your eye on this space. Factories in Shenzhen are making better, more modular parts, and the same supply chain economics that are driving down the cost of smart phones and smart cars, will give hobbyist engineers all the simple hardware components they could ever need. This will power a future of proliferated devices that have internet connectivity and “talk” to each other to enable user experiences we wouldn’t dream of today. And naturally, with this will come problems that we cannot anticipate as well.

On today’s episode, Andrew discusses how JavaScript can be used on hardware. Jeff and Andrew talk about the players in the hardware space, as well as how the big cloud players like AWS and Azure are positioning themselves to be the data lakes for the internet of things. Andrew is giving a talk about this at the 2016 O’Reilly Fluent Conference. If you want to win a free ticket to Fluent, tweet about your favorite episode of Software Engineering Daily and tag @fluentconf and @software_daily.

Andrew Chalkley is a hardware hobbyist, software engineer and a full-time teacher at Treehouse.

", + "Episodes Title": "JavaScript and the Internet of Things with Andrew Chalkley", + "Episodes Uid": "SED4021315048", + "Episodes Audio File": "560d05ec35c6a023ed5f635b6442be6e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6r4", + "Episodes ID": "ea88aa08-e328-11ea-91a2-e39568be6b60", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_14_Matillion.mp3", + "Episodes Pubdate Date": "2020-02-14", + "Episodes Summary": "

A data warehouse provides low latency access to large volumes of data. 

A data warehouse is a crucial piece of infrastructure for a large company, because it can be used to answer complex questions involving a large number of data points. But a data warehouse usually cannot hold all of a company’s data at any given time. Users need to move a subset of the data into the data warehouse by reading large files from a data lake on disk and putting that data into the data warehouse.

The process of moving data from one place into another is broken down into three sequential steps, often called “ETL” (extract, transform, load) or “ELT” (extract, load, transform). In ETL, the data is extracted from a source such as a data lake, transformed into a schema that is customized for the data warehouse application, and then loaded into the data warehouse. In ELT, the last two steps are reversed, because modern systems can often leave the necessary schema transformation until after the data has been loaded into the data warehouse.

Matthew Scullion is the CEO of Matillion, a company that specializes in building tools for data transformations. Matthew joins the show to talk about the problem of data transformation, and how that problem has evolved over the nine years since he started Matillion.

If you enjoy the show, you can find all of our past episodes about data infrastructure by going to SoftwareDaily.com and searching for the technologies or companies mentioned. And if there is a subject that you want to hear covered, feel free to leave a comment on the episode, or send us a tweet @software_daily.

", + "Episodes Title": "Data Warehouse ETL with Matthew Scullion", + "Episodes Uid": "SED1008110909", + "Episodes Audio File": "3c3ae4fa59357920802eac83ab92af05.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 768, + "Episodes ID": "e9678aae-e328-11ea-91a2-f366b3833369", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_05_07_DropboxEngineering.mp3", + "Episodes Pubdate Date": "2020-05-08", + "Episodes Summary": "

Dropbox is a consumer storage product with petabytes of data. Dropbox was originally started on the cloud, backed by S3. Once there was a high enough volume of data, Dropbox created its own data centers, designing hardware for the express purpose of storing user files. 

Over the last 13 years, Dropbox’s infrastructure has developed hardware, software, networking, data center infrastructure, and operational procedures that make the cloud storage product best in class.

Andrew Fong has been an engineer at Dropbox for 8 years. He joins the show to talk about how the Dropbox engineering organization has changed over that period of time, and what he is doing at the company today.

", + "Episodes Title": "Dropbox Engineering with Andrew Fong", + "Episodes Uid": "SED7292552964", + "Episodes Audio File": "fc7883e37ce3a14f6baf70bebacf5269.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5z4", + "Episodes ID": "ed0eb0b0-e328-11ea-91a2-db7a364833be", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_24_TechLitAfrica.mp3", + "Episodes Pubdate Date": "2019-07-24", + "Episodes Summary": "

In the developed world, it is easy to take for granted that we grew up with computers. Technology is so pervasive in the United States that we have debates about how early in child development a human should be given a smartphone.

Across much of Africa, there is a shortage of access to computers. Children grow up without much exposure to computers at all. Smartphones are starting to proliferate the continent, but the bandwidth limitations prevent the sort of unrestricted mobile Internet usage that many of us have in the west.

Tyler Cinnamon is a software engineer and the co-founder of TechLitAfrica, an organization dedicated to improving technology literacy and reducing poverty in Africa. TechLitAfrica takes old computers from the United States which are no longer in use and repurposes those computers with educational software and a downloaded subset of the Internet. Then, TechLitAfrica takes those computers to Africa and sets them up as computer labs.

Tyler joins the show to talk through the technical and cultural challenges of building TechLitAfrica.

", + "Episodes Title": "TechLitAfrica: Computer Literacy in Africa with Tyler Cinnamon", + "Episodes Uid": "SED6120956160", + "Episodes Audio File": "bedca4723e0c3c1db62cb42f387f0ca9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7hj", + "Episodes ID": "e850eeb2-e328-11ea-91a2-4be7c454be40", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_29_VeriSIM.mp3", + "Episodes Pubdate Date": "2020-07-29", + "Episodes Summary": "

Drug trials can lead to new therapeutics and preventative medications being discovered and placed on the market. Unfortunately, these drug trials typically require animal testing. This means animals are killed or harmed as a result of needing to verify that a drug will not kill humans.

Animal testing is unavoidable, but the extent to which testing needs to occur can be reduced by inserting machine learning models which simulate the effects of a drug on the human body. If the simulated effect is negative enough, animal testing doesn’t need to be run, thus no animals need to be harmed.

Bryan Vicknair and Jason Walsh work at VeriSIM Life, a company which makes software simulations of animals. These simulations can be used to model drug testing, and change the workflow for drug trials. They join the show to talk through the mechanics of drug testing, and how VeriSIM Life fits into that workflow.

", + "Episodes Title": "Drug Simulations with Bryan Vicknair and Jason Walsh", + "Episodes Uid": "SED9940734014", + "Episodes Audio File": "2df56f35832a4e96b21ee9a166b10617.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6go", + "Episodes ID": "eb791484-e328-11ea-91a2-5b058c41c06e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_23_FindCollabsDepsCloud.mp3", + "Episodes Pubdate Date": "2019-11-23", + "Episodes Summary": "

New software abstractions always take advantage of the abstractions that have been built before.

Software libraries allow us to import code that sits on the same host as a new program. Open source software let us copy and paste existing code, or clone entire repositories. Cloud providers offer hosted tools and APIs that we can leverage to develop scalable, easy-to-use infrastructure.

When existing pieces of software are built into new software, the existing software becomes a dependency. Managing those dependencies is an engineering problem. Mya Pitzeruse is the founder of deps.cloud, a project with the goal of improving dependency changes across a company’s ecosystem. In today’s show, we talk about the modern dependency issues of a large company, and her perspective on how to address them. Mya has developed the project in public on FindCollabs, and we also spend some time talking about building in the open.

", + "Episodes Title": "Cloud Dependencies with Mya Pitzeruse", + "Episodes Uid": "SED4766273026", + "Episodes Audio File": "70da804eb66a4d0f4bfe4b1c71255a96.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6zl", + "Episodes ID": "ea094c40-e328-11ea-91a2-9fe494703156", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_24_Datomic.mp3", + "Episodes Pubdate Date": "2020-03-24", + "Episodes Summary": "

Datomic is a database system based on an append-only record keeping system. Datomic users can query the complete history of the database, and Datomic has ACID transactional support. The data within Datomic is stored in an underlying database system such as Cassandra or Postgres. The database is written in Clojure, and was co-authored by the creator of Clojure, Rich Hickey.

Datomic has a unique architecture, with a component called a Peer, which gets embedded in an application backend. A Peer stores a subset of the database data in memory in this application backend, improving the latency of database queries that hit this caching layer.

Marshall Thompson works at Cognitect, the company that supports and sells the Datomic database. Marshall joins the show to talk about the architecture of Datomic, its applications, and the life of a query against the database.

We’re looking for new show ideas, so if you have any interesting topics, please feel free to reach out via twitter or email us at  jeff@softwareengineeringdaily.com

", + "Episodes Title": "Datomic Architecture with Marshall Thompson", + "Episodes Uid": "SED6300605461", + "Episodes Audio File": "e3893d400fb138e412b06f7a197abe45.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 789, + "Episodes ID": "e94b5bcc-e328-11ea-91a2-bf1827586f02", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_16_softwaredaily_episode.mp3", + "Episodes Pubdate Date": "2020-05-16", + "Episodes Summary": "

For the last five months, we have been working on a new version of Software Daily, the platform we built to host and present our content. 

We are creating a platform that integrates the podcast with a set of other features that make it easier to learn from the audio interviews. 

Software Daily includes the following features:


\nThe world of software is large, and growing bigger every day. Software Daily is a place to explore this world of software companies and projects.

If the podcast is a useful resource for you to learn about software, then Software Daily might also provide you with value. This post (and episode) is a brief description of the features that we have built into Software Daily.

If you want to listen to Software Engineering Daily without ads, you can become a paid subscriber, paying $10/month or $100/year by going to softwaredaily.com/subscribe. We now have an RSS feed that paid customers can add to a podcast player like Overcast (on iOS) or Podcast Addict (on Android). You can also listen to the premium episodes using our apps for iOS or Android.

Whether you are a listener who is fine with listening to ads, or you are a listener who pays to hear episodes without ads, we are happy to have you tuning in.

Apple podcasts limits the number of episodes in an RSS feed to 300. The feed with the last 300 episodes is available by searching for Software Daily. In total, we have more than 1200 episodes in our back catalog.

Listeners often want to find all our episodes on React, or Kubernetes, or serverless, or self-driving cars. We have been covering these topics for years, and much of the old content has retained its value. Software Daily allows you to easily find all the episodes relating to a subject that you are interested in.

You can also find our most popular episodes, ranked by how people interact with them.

Additionally, episode transcripts have interactive features with highlighting, commenting, and discussions. We want to create a Medium-like experience for the episodes.

Software Daily is a place where listeners can write about the topics they are listening to. When you are listening to lots of episodes about a topic such as GraphQL, you may find it useful to write about that topic as a form of active learning. The topic pages also have a Q&A section. Post questions about a topic, or post an answer. Engage in the community dialogue surrounding a topic you are passionate or curious about. If there is a topic you want to write about, check out softwaredaily.com/write.

We will be turning the best written content into short podcast episodes published on the weekends where we will read your contribution and mention your name. If you write something awesome, we want to turn it into audio for larger distribution. 

Every topic on Software Daily has a Q&A section. We have covered lots of niche software companies and open source projects, and on Software Daily we want to collect more information about the world of software with Q&A.

If you want to write about a specific company or topic that you heard about on Software Daily, Q&A is also an option. Our goal with Q&A is to provide a companion experience to listening to the podcast. It is not always easy to retain what you hear in a podcast episode. Answering some questions after you listen to an episode can help with that retention.

Are you looking to hire someone specific in the world of software? Post a job on the Software Daily jobs board. We will be announcing some of these jobs on the podcast, especially the more interesting postings, and ones that align with content we are producing.

We appreciate you tuning into Software Daily. We would welcome your feedback, and hope you take the time to check out SoftwareDaily.com.

", + "Episodes Title": "Software Daily", + "Episodes Uid": "SED9665414994", + "Episodes Audio File": "dbd7cbefd65ad152fef6b06b470c8af7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "67a", + "Episodes ID": "ec5dad74-e328-11ea-91a2-fb5c4c0af81d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_17_KafkaApplications.mp3", + "Episodes Pubdate Date": "2019-09-17", + "Episodes Summary": "

Ever since Apache Kafka was open sourced from LinkedIn, it has been used to solve a wide variety of problems in distributed systems and data engineering.

Kafka is a distributed messaging queue that is used by developers to publish messages and subscribe to topics with a certain message type. Kafka allows information to flow throughout a company such that multiple systems can consume the messages from a single sender. 

In previous shows, we have covered design patterns within Kafka, Kafka streams, event sourcing with Kafka, and many other subjects relating to the technology. Kafka is broadly useful, and new strategies for using Kafka continue to emerge as the open source project develops new functionality and becomes a platform for data applications.

In today’s episode, Tim Berglund returns to Software Engineering Daily for a discussion of how applications are built today using Kafka–including systems that are undergoing a refactoring, data engineering applications, and systems with a large number of communicating services.

If you are interested in learning more about how companies are using Kafka, the Kafka Summit in San Francisco is September 30th – October 1st. Companies like LinkedIn, Uber, and Netflix will be talking about how they use Kafka. Full disclosure: Confluent (the company where Tim works) is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Kafka Applications with Tim Berglund", + "Episodes Uid": "SED4068052481", + "Episodes Audio File": "758879c8a2f03aa60e919b8dc40690f5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6xc", + "Episodes ID": "ea3c08c4-e328-11ea-91a2-abcdaf6b692c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_09_DBT_DataBuildTool.mp3", + "Episodes Pubdate Date": "2020-03-09", + "Episodes Summary": "

A data warehouse serves the purpose of providing low latency queries for high volumes of data. A data warehouse is often part of a data pipeline, which moves data through different areas of infrastructure in order to build applications such as machine learning models, dashboards, and reports.

Modern data pipelines are often associated with the term “ELT” or Extract, Load, Transform. In the “ELT” workflow, data is taken out of a source such as a data lake, loaded into a data warehouse, and then transformed within the data warehouse to create materialized views on the data. Data warehouse queries are usually written in SQL, and for the last 50 years, SQL has been the primary language for executing these kinds of queries. 

DBT is a system for data modeling that allows the user to write queries that involve a mix of SQL and a templating language called Jinja. Jinja allows the analyst to blend imperative code along with the declarative SQL. Tristan Handy is the CEO of Fishtown Analytics, the company that created DBT, and he joins the show to discuss how DBT works, and the role it plays in modern data infrastructure.

", + "Episodes Title": "DBT: Data Build Tool with Tristan Handy", + "Episodes Uid": "SED8636394264", + "Episodes Audio File": "7b794eb6640b845350556ce61453dfdc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6nf", + "Episodes ID": "eace3e92-e328-11ea-91a2-839cffc21bb6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_27_Mattermost.mp3", + "Episodes Pubdate Date": "2020-01-27", + "Episodes Summary": "

Chat systems have been a part of software development for decades. Older systems like Pidgin and Yammer were surpassed by newer systems like HipChat. And when Slack was created, it quickly became a part of most software companies. But Slack does not fulfill the needs of every company.

Mattermost is an open-source chat system. Mattermost can be configured to work within enterprises that have strong constraints around compliance and data governance. Whereas Slack is a SaaS product that requires users to send their data to the cloud servers managed by Slack, Mattermost allows the enterprise to decide how data moves through services, and where the databases are hosted.

Ian Tien is the CEO of Mattermost, and he joins the show to talk about why many companies need their chat system to be hosted in a private cloud or on-premises. In a previous episode with CTO Corey Hulen we discussed the engineering behind the company. In today’s episode, we explore the management and strategy of the business, as well as some additional engineering, since Ian Tien’s background is as a software engineer and computer scientist.

", + "Episodes Title": "Mattermost with Ian Tien", + "Episodes Uid": "SED6378572983", + "Episodes Audio File": "a72a28674968d509c29bf539ec2abef2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5i0", + "Episodes ID": "eecc7d60-e328-11ea-91a2-77ae44ead4fe", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_26_SecuritywithSteveHerrod.mp3", + "Episodes Pubdate Date": "2019-03-26", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Steve Herrod was the CTO at VMware and now works as a managing director at General Catalyst, where he focuses on investments relating to security.

Large enterprises are difficult to secure. An enterprise has sprawling infrastructure, with both on-prem and cloud infrastructure. Identity management systems, vulnerability scanning, secure network infrastructure, and policy management tools are just a few example areas where enterprises spend billions of dollars on security software.

Threats often make their way into an enterprise by way of social engineering. This can result in phishing attacks, corporate espionage, and ransomware. Protecting against social engineering is very difficult, as there are so many channels to communicate through–Facebook Messenger, Linkedin, email, and ad networks can all be used to perform social engineering attacks.

Enterprise security software is a very different business from other types of software companies. Unlike developer tools or cloud infrastructure, security software is usually not self-serve. Security solutions usually require a longer sales and integration process with a customer.

Steve Herrod joins the show to talk about the enterprise security world, the go-to-market strategy for successful security companies, and his perspective on what makes for a viable venture capital investment.

", + "Episodes Title": "Security Businesses with Steve Herrod", + "Episodes Uid": "SED8971518357", + "Episodes Audio File": "7e61e27e2253dcbdc6f4d1e2cc43e12a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 200000, + "Episodes ID": "0c08cb68-e329-11ea-91a2-075cdf3ac1f5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/architecture_edited.mp3", + "Episodes Pubdate Date": "2017-01-05", + "Episodes Summary": "

When a useful new technology comes out, companies that are in a position to adopt that new technology can gain an edge over competitors. As our industry grows and moves faster, these kinds of changes are coming faster–some recent examples are Docker, ReactJS, and Kubernetes.

Evolutionary architecture supports incremental, guided change as a first principle along multiple dimensions. A company with an evolutionary architecture is structured to evolve in response to changes inside the company (such as a decision to change the product) or outside the company (such as the emergence of Docker). Neal Ford is an architect at ThoughtWorks and one the creators of the evolutionary architecture concept.

", + "Episodes Title": "Evolutionary Architecture with Neal Ford", + "Episodes Uid": "SED6931130680", + "Episodes Audio File": "ce83db10b6de41281f94f3975e41e6d1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2cb", + "Episodes ID": "0f08a18a-e329-11ea-91a2-cf83ffd24f37", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/developertools_edited.mp3", + "Episodes Pubdate Date": "2016-12-07", + "Episodes Summary": "

When you are working on a program, a lot of things are going through your head. In some sense, you become part machine when you are programming. Learnable Programming is a concept that facilitates this, by showing developers what the computer is doing in real time, before compiling.

In this episode, Josh Varty, co-founder of Code Connect Inc., talks to Edaena Salinas about incorporating concepts from Learnable Programming into Visual Studio and C# by showing developers what the computer is thinking while they are typing. Code Connect lets a developer immediately see what value a variable is taking, and provide test values to troubleshoot a portion of code to understand how different code paths are going to work. This is instead of having to compile and run the full program.

If you have ever thought about making developer tools for an IDE or a programming language, this episode provides some great information.

", + "Episodes Title": "Developer Tools with Josh Varty", + "Episodes Uid": "SED7542729991", + "Episodes Audio File": "5c4104b87602d9bc173166e6dbe4bee8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25a", + "Episodes ID": "15c204b2-e329-11ea-91a2-cb79bda618cb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Haskell_in_Production_Edited.mp3", + "Episodes Pubdate Date": "2016-08-31", + "Episodes Summary": "

The Haskell programming language is often thought of as an academic tool, useful for teaching students about monads and functors, but not much else. But there are advantages to using Haskell as a production backend language.

Better is a company built with Haskell on the backend, and Carl Baatz wrote a blog post detailing his experiences using Haskell. He joins the show to give a detailed explanation of why a company might want to use Haskell on the backend, from software architecture, to testing, to hiring.

", + "Episodes Title": "Haskell in Production with Carl Baatz", + "Episodes Uid": "SED8496639147", + "Episodes Audio File": "49c6e2f6a4953492073419812611f0e5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 269, + "Episodes ID": "1513b970-e329-11ea-91a2-a72f9116a474", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Unikernels_Edited.mp3", + "Episodes Pubdate Date": "2016-09-14", + "Episodes Summary": "

Unikernels allow us to specify the minimum features of an operating system we need to deploy our applications. We’ve had many shows about containers, which allow you to deploy your application on top of a segregated portion of an operating system. Unikernels are different because they can be deployed directly to bare metal or to a hypervisor.

Idit Levine works on Unikernels at EMC. We had an interview a few weeks ago with her colleague Scott Weiss, and today’s conversation goes deeper into the motivations for Unikernels, the problems they solve, and the project she is leading called Unik, which seeks to add the degree of usability and adoption to Unikernels that Docker brought to containers.

", + "Episodes Title": "Unikernels with Idit Levine", + "Episodes Uid": "SED6696846378", + "Episodes Audio File": "0f21e737936549dcbf0d2558d4892587.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "88f23326-f6d4-11ea-8382-e726d48c6b32", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-15", + "Episodes Summary": "


", + "Episodes Title": "Internet Archive Book Scanning with Davide Semenzin", + "Episodes Uid": "SED4199710525", + "Episodes Audio File": "176e28b5e72fe0c652843f1dd5933856.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6h5", + "Episodes ID": "eb62017c-e328-11ea-91a2-abf702d86bbe", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Economics_Edited.mp3", + "Episodes Pubdate Date": "2019-11-29", + "Episodes Summary": "

Originally published July 14, 2016

EconTalk is a weekly economics podcast that has been going for a decade. On EconTalk, Russ Roberts brings on writers, intellectuals, and entrepreneurs for engaging conversations about the world as seen through the lens of economics.

Russ Roberts is today’s guest, and it is a treat because I have been listening to EconTalk since 2006 and it was a central point of inspiration for what Software Engineering Daily has become. On this episode, we talk about how software impacts the world economically, from bitcoin’s promise of zero cost transactions to the opportunities and regulatory challenges of the software-enabled gig economy.

", + "Episodes Title": "Economics of Software with Russ Roberts Holiday Repeat", + "Episodes Uid": "SED9886300614", + "Episodes Audio File": "403c45e7b54e46b92c9c35b555e0168c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7fk", + "Episodes ID": "e88653f4-e328-11ea-91a2-b348a7e7db4e", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_14_Multimesh.mp3", + "Episodes Pubdate Date": "2020-07-14", + "Episodes Summary": "

A service mesh provides routing, load balancing, policy management, and other features to a set of services that need to communicate with each other. The mesh can simplify operations across these different services by providing an interface to configure them. 

There are lots of different vendors who offer service mesh technology: AWS has AppMesh, Google has Istio (which is open source), Buoyant has Linkerd (which is also open source), and HashiCorp has Consul Connect. Unfortunately, these service meshes do not all play well together. And at a large enough company, different teams will be setting up different service meshes. So it would be useful for services in those different meshes to be able to communicate with each other.

Luke Kysow is an engineer at HashiCorp where he works on Consul Connect, and he joins the show to discuss service mesh usage, adoption, and possible strategies for maintaining multiple service meshes within a single organization.

", + "Episodes Title": "Multimesh with Luke Kysow", + "Episodes Uid": "SED9330036559", + "Episodes Audio File": "6f9a63284fc9d7d8e0748eceab12364e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7kb", + "Episodes ID": "b8536e56-e91d-11ea-bd31-1fd7c053c471", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_28_TuneHyperparameterTuning.mp3", + "Episodes Pubdate Date": "2020-08-28", + "Episodes Summary": "

Hyperparameters define the strategy for exploring a space in which a machine learning model is being developed. Whereas the parameters of a machine learning model are the actual data coming into a system, the hyperparameters define how those data points are fed into the training process for building a model to be used by an end consumer.

A different set of hyperparameters will yield a different model. Thus, it is important to try different hyperparameter configurations to see which models end up performing better for a given application. Hyperparameter tuning is an art and a science.

Richard Liaw is an engineer and researcher, and the creator of Tune, a library for scalable hyperparameter tuning. Richard joins the show to talk through hyperparameters and the software that he has built for tuning them.

", + "Episodes Title": "Hyperparameter Tuning with Richard Liaw", + "Episodes Uid": "SED4672185690", + "Episodes Audio File": "948a18f2ec1c12868b9f2548bfc1168e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7d3", + "Episodes ID": "e89e6c28-e328-11ea-91a2-fbf126bf81ef", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_29_AWSGoodParts.mp3", + "Episodes Pubdate Date": "2020-07-07", + "Episodes Summary": "

AWS has over 150 different services. Databases, log management, edge computing, and lots of others. Instead of being overwhelmed by all of these products, an engineering team can simplify their workflow by focusing on a small subset of AWS services–the defaults.

Daniel Vassalo is the author of The Good Parts of AWS. An excerpt from the book: “The cost of acquiring new information is high and the consequence of deviating from a default choice is low, so sticking with the default will likely be the optimal choice. A default choice is any option that gives you very high confidence that it will work.” Having confidence in your workflow–even if it is a simple workflow–has advantages.

S3, EC2, Elastic Load Balancers: for simple web applications, this is really all you need to build your business. Daniel Vassallo worked at AWS for more than 8 years before leaving to become an entrepreneur and author. He joins the show to talk about what the good parts of AWS are, and his strategy for building applications with that subset of services.

", + "Episodes Title": "The Good Parts of AWS with Daniel Vassallo", + "Episodes Uid": "SED2744141959", + "Episodes Audio File": "8aa8343f5fe5b46e5ac2b5139a79bde3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1oe", + "Episodes ID": "21d154ba-e329-11ea-91a2-2baa85f5635a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/bridge_foundry_Edited.mp3", + "Episodes Pubdate Date": "2016-03-03", + "Episodes Summary": "

Technology careers are not as accessible to certain demographics, such as women. Sarah Allen is working to change that through education and outreach. Sarah Allen created RailsBridge and Bridge Foundry, a pair of organizations working to make technology more accessible to people who are underrepresented in tech.

RailsBridge workshops are a fun and free way to get started with Ruby, Rails or other technologies. RailsBridge was so successful that Sarah created Bridge Foundry, which has an even wider variety of free workshops, from Clojure to Go to Mobile. This is an inspirational episode of Software Engineering Daily, and is a great learning opportunity for anyone interested in building a community.

", + "Episodes Title": "Bridge Foundry with Sarah Allen", + "Episodes Uid": "SED6393614451", + "Episodes Audio File": "afe0bab4bd9f88aaed85ffaae85af394.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7eq", + "Episodes ID": "e8907604-e328-11ea-91a2-4f0f495a7c08", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_10_Strapi.mp3", + "Episodes Pubdate Date": "2020-07-10", + "Episodes Summary": "

WordPress has been a dominant force in the world of online publishing for many years because of how battle-tested it is. WordPress is the definitive leader in CMS technology. But there have always been alternatives. 

Drupal, Ghost, and other open source CMSes. More recently, there has been an emergence of the headless CMS, such as Contentful, which decouples the CMS backend from the frontend presentation layer.

Strapi is a popular open source headless CMS. Pierre Burgy is the founder of Strapi, and he joins the show to talk about the CMS category, the role that Strapi fills, and the technology behind Strapi.

", + "Episodes Title": "Strapi: Headless CMS with Pierre Burgy", + "Episodes Uid": "SED6711902323", + "Episodes Audio File": "6a589d3e751af115f269c617bf27abb9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 204, + "Episodes ID": "1ba8738e-e329-11ea-91a2-d7a8897a4dcc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Tech_G_Edited.mp3", + "Episodes Pubdate Date": "2016-06-07", + "Episodes Summary": "

The software industry has a severe lack of women. There are numerous root causes of this diversity problem. Families do not encourage women to enter math and science. The media portrays most programmers as white males. Our industry often picks up on the signals of the broader society and perpetuates them.

Reversing this trend of low female involvement in computer science could have tremendous positive impact, and Jenine Beekhuyzen joins the show today to discuss how she she is taking action to improve the pipeline of young women entering computer science.

", + "Episodes Title": "Tech Girls Movement with Jenine Beekhuyzen", + "Episodes Uid": "SED6280645923", + "Episodes Audio File": "45f6b545b3081e42c6e1761b4432d397.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "68a", + "Episodes ID": "ec2f0b4a-e328-11ea-91a2-47995d5dabcf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_01_CruiseEngineering.mp3", + "Episodes Pubdate Date": "2019-10-01", + "Episodes Summary": "

The development of self-driving cars is one of the biggest technological changes that is under way.

Across the world, thousands of engineers are working on developing self-driving cars. Although it still seems far away, self-driving cars are starting to feel like an inevitability. This is especially true if you spend much time in downtown San Francisco, where you will see a self-driving car being tested every day. Much of the time, that self-driving car will be operated by Cruise.

Cruise is a company that is building a self-driving car service. The company has hundreds of engineers working across the stack, from computer vision algorithms to automotive hardware. Cruise’s engineering requires engineers who can work with cloud tools as well as low-latency devices. It also requires product developers and managers to lead these different teams.

The field of self-driving is very new. There is not much literature available on how to build a self-driving car. There is even less literature on how to manage a team of engineers that are building, testing, and deploying software and hardware for real cars that are driving around the streets of San Francisco.

Mo Elshenawy is VP of engineering at Cruise, and he joins the show to talk about the engineering that is required to develop fully self-driving car technology, as well as how to structure teams to align the roles of product design, software engineering, testing, machine learning, and hardware. 

Full disclosure: Cruise is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Cruise: Self-Driving Engineering with Mo Elshenawy", + "Episodes Uid": "SED6975876104", + "Episodes Audio File": "c9140bfa440e36c1e124396e5b9a0532.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7eh", + "Episodes ID": "e8a7386c-e328-11ea-91a2-7b45ebaac3bc", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_03_Deepgram.mp3", + "Episodes Pubdate Date": "2020-07-03", + "Episodes Summary": "

Deepgram is an end-to-end deep learning platform for speech recognition. Unlike the general purpose APIs from Google or Amazon, Deepgram models are custom-trained for each customer. Whether the customer is a call center, a podcasting company, or a sales department, Deepgram can work with them to build something specific to their use case.

Sound data is incredibly rich. Consider all the features in a voice recording: volume, intonation, inflection. And once the speech is transcribed, there are many more features that can be discovered from the text transcription.

Scott Stephenson is the CEO of Deepgram, and he joins the show to talk through end-to-end deep learning for speech, as well as the dynamics of the business and the deployment strategy for working with customers.

", + "Episodes Title": "Deepgram: End-to-End Speech Recognition with Scott Stephenson", + "Episodes Uid": "SED3945124346", + "Episodes Audio File": "3a635b1b3127ddb62d065736cc9d3691.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 756, + "Episodes ID": "e97f4554-e328-11ea-91a2-bfbb0a3da9c5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_05_01_DataLakeHouse.mp3", + "Episodes Pubdate Date": "2020-05-01", + "Episodes Summary": "

A data warehouse is a system for performing fast queries on large amounts of data. A data lake is a system for storing high volumes of data in a format that is slow to access. A typical workflow for a data engineer is to pull data sets from this slow data lake storage into the data warehouse for faster querying.

Apache Spark is a system for fast processing of data across distributed datasets. Spark is not thought of as a data warehouse technology, but it can be used to fulfill some of the responsibilities. Delta is an open source system for a storage layer on top of a data lake. Delta integrates closely with Spark, creating a system that Databricks refers to as a “data lakehouse.”

Michael Armbrust is an engineer with Databricks. He joins the show to talk about his experience building the company, and his perspective on data engineering, as well as his work on Delta, the storage system built for the Spark ecosystem.

", + "Episodes Title": "Data Lakehouse with Michael Armbrust", + "Episodes Uid": "SED9590703672", + "Episodes Audio File": "aa99a9689937236a1eccdedb74f003a9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "11a", + "Episodes ID": "2a283142-e329-11ea-91a2-dfe9d80fc854", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Uber_Edited.mp3", + "Episodes Pubdate Date": "2015-12-04", + "Episodes Summary": "

Uber is a transportation and logistics company that manages many aspects of its ride-sharing services through mobile apps and distributed technology. Uber faces unique challenges in rapidly scaling its services internationally, and at one point increased its developer headcount from 200 to over 1000 in less than a year.

Matt Ranney is the Chief Systems Architect at Uber and was previously a founder and CTO of Voxer. At QCon San Francisco, he gave a talk called Scaling Uber.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Scaling Uber with Matt Ranney", + "Episodes Uid": "SED9602251169", + "Episodes Audio File": "983dd76ca58e2c5d48033fd4014518cd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 158, + "Episodes ID": "281a0dda-e329-11ea-91a2-cf42618750d0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Kafka_Edited.mp3", + "Episodes Pubdate Date": "2015-12-18", + "Episodes Summary": "

The stream processing paradigm is increasingly being adopted by applications that need to process and handle large volumes of data. Apache Kafka is an open-source distributed publish-subscribe messaging system that is built to support streaming data processing.

Neha Narkhede is the one of the creators of Apache Kafka, which she built to address engineering challenges while working at LinkedIn. She is also the co-founder of Confluent, which builds enterprise products around Kafka.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Demystifying Stream Processing with Neha Narkhede", + "Episodes Uid": "SED3426541106", + "Episodes Audio File": "e5fb38d0e7babc94cb6d36f79afb4261.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6a9", + "Episodes ID": "ec09eebe-e328-11ea-91a2-175c94fb656b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_11_WebFlow.mp3", + "Episodes Pubdate Date": "2019-10-11", + "Episodes Summary": "

Webflow is a platform for building applications without programming.

Software engineering has barely been around for 30 years. Over that period of time, there have been many attempts to create a platform that allows for the creation of software without writing a line of code. Most of these systems have not been able to fulfill that task. And this should come as no surprise. It is hard enough to build an application if you know how to program. 

Vlad Magdolin has been working on Webflow for more than seven years. He has persisted through multiple failed attempts at building Webflow, and pushed past continuous rejection from investors who did not see the viability of his vision. 

As Vlad patiently worked on Webflow with his two co-founders, the power of the web browser slowly improved. V8 became a powerful runtime that could deliver the performance necessary to build applications visually in the browser. The unmet goals of past WYSIWYG application platforms faded into irrelevance, as Webflow came into being and allowed for an entirely new type of software development, driven by a visual interface in the browser.

Webflow is one of the coolest, most ambitious software platforms in existence. Vlad joins the show to discuss Webflow and the future of software development.

", + "Episodes Title": "Webflow: No-Code with Vlad Magdolin", + "Episodes Uid": "SED7481975048", + "Episodes Audio File": "57a2c277092fb688d4faa2c4ce4f3618.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "67b", + "Episodes ID": "ec58e23a-e328-11ea-91a2-27e8ab8bff8d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_18_MongoProduct.mp3", + "Episodes Pubdate Date": "2019-09-18", + "Episodes Summary": "

Modern databases consist of multiple servers that host the data in a distributed fashion. Using multiple servers allows a database to be resilient to the failure of any one database node, because copies of the data are shared to other servers. A multi-node setup also lets the database grow beyond the size of data that could be hosted on a single node.

Although a distributed database gains in scalability and resiliency, a database that runs across multiple nodes has a variety of problems that are not faced by a database running on a single node. Every operation with a distributed database becomes more complex than the single-node database.

For example, if you make a query to your distributed database, you might not be able to rely on the answer that you get from a single database node, because the other database nodes might have been involved in transactions that have not propagated to all of the nodes.

Aly Cabral is a lead product manager at MongoDB and co-author of a paper on causal consistency in MongoDB. Aly joins the show to discuss the engineering of distributed databases and her experience architecting MongoDB. Full disclosure: MongoDB is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Distributed Databases with Aly Cabral", + "Episodes Uid": "SED8184680759", + "Episodes Audio File": "08936c171146231d2060b195e20557b3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ia", + "Episodes ID": "eb316b0c-e328-11ea-91a2-9f1aa6870973", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_13_GitLabEng.mp3", + "Episodes Pubdate Date": "2019-12-13", + "Episodes Summary": "

GitLab is a company that builds an open source platform for managing git repositories.

GitLab was started in 2012, and has grown to have a large enterprise business with additional products such as continuous integration and security tooling. GitLab is also known for being a large, entirely remote workforce. GitLab does not have any offices, and the employees mostly communicate through Slack, email, and GitLab itself.

Marin Jankovski was the first full-time engineer to join GitLab after the company was started. Marin joins the show to talk about the early days of GitLab, the evolution of the remote culture, and how product development works at GitLab today. He also talks about the experience of being a fast-growing company in the public spotlight of the software industry.

", + "Episodes Title": "GitLab Engineering with Marin Jankovski", + "Episodes Uid": "SED4045177991", + "Episodes Audio File": "70df5b16e19a4908fd55f5181805edbf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6wh", + "Episodes ID": "ea4f238c-e328-11ea-91a2-578c5e7105a7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_03_JSFundamentalsRyanFlorence.mp3", + "Episodes Pubdate Date": "2020-03-03", + "Episodes Summary": "

ReactJS began to standardize frontend web development around 2015. The core ideas around one-way data binding, JSX, and components caused many developers to embrace React with open arms. There has been a large number of educators that have emerged to help train developers wanting to learn React.

A new developer learning React has numerous questions around frameworks, state management, rendering, and other best practices. In today’s episode, those questions are answered by Ryan Florence, a co-founder of React Training.

React Training is a company devoted to helping developers learn React that trains large companies like Google and Netflix how to use React. Ryan has a strong understanding of how to be productive with React, and in today’s episode, he explains some of the fundamentals that commonly confuse new students of React.

Ryan is also speaking at Reactathon, a San Francisco JavaScript conference taking place March 30th and 31st in San Francisco. This week we will be interviewing speakers from Reactathon, and if you are interested in JavaScript and the React ecosystem then stay tuned, and if you hear something you like, you can check out the Reactathon conference in person.

", + "Episodes Title": "React Fundamentals with Ryan Florence", + "Episodes Uid": "SED6162549526", + "Episodes Audio File": "4e109635db6cf8fa68515f450f67c8c2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 778, + "Episodes ID": "e9593508-e328-11ea-91a2-a325919a2db1", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_12_Grapl.mp3", + "Episodes Pubdate Date": "2020-05-13", + "Episodes Summary": "

A large software company such as Dropbox is at a constant risk of security breaches. These security breaches can take the form of social engineering attacks, network breaches, and other malicious adversarial behavior. This behavior can be surfaced by analyzing collections of log data.

Log-based threat response is not a new technique. But how should those logs be analyzed? Grapl is a system for modeling log data as a graph, and analyzing that graph for threats based on how nodes in the graph have interacted. By building a graph from log data, Grapl can classify interaction patterns that correspond to threats.

Colin O’Brien is the creator of Grapl, and he joins the show to discuss security, as well as threat detection and response.

", + "Episodes Title": "Grapl: Graph-Based Detection and Response with Colin O’Brien", + "Episodes Uid": "SED8353728929", + "Episodes Audio File": "6a3b6dd158ea230b2461b9f44f59b3d9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xj", + "Episodes ID": "ed20b17a-e328-11ea-91a2-7f022dc9f5dc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_18_FacebookOpenSourceManagement.mp3", + "Episodes Pubdate Date": "2019-07-18", + "Episodes Summary": "

Facebook has released open source software projects that have changed the industry. The most impactful projects to date are the React frontend user interface tools: ReactJS and React Native.

Before React became popular, there were multiple competing solutions for the dominant frontend JavaScript framework. React became the most prominent because of its invention of JSX, its one-way data flow, and the strength of its community.

The React community is led by Facebook engineers. Facebook has a full-time team dedicated to improving React. Facebook also has the benefit of seeing the hardest problems in web development ahead of the rest of the industry, since Facebook is always pushing the leading edge of what software can do.

As React evolves, Facebook itself is the first user of updates to the libraries. Engineers on the React team will proactively update the applications on other teams with new React code. In this way, Facebook’s React team is similar to a platform engineering team, except the open source community benefits from the improvements as well.

Tom Occhino is an engineering director at Facebook. He joins the show to discuss his ten years of experience at the company and his role today as a senior leader in charge of open source developers.

", + "Episodes Title": "Facebook Open Source Management with Tom Occhino", + "Episodes Uid": "SED6207585722", + "Episodes Audio File": "0dd8eb142e28a65a83036226f2080fbe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "qj", + "Episodes ID": "30696850-e329-11ea-91a2-c79f9f69ddd0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/david_nimit_fullstack_academy.mp3", + "Episodes Pubdate Date": "2015-10-06", + "Episodes Summary": "

Fullstack Academy is a 13-week immersive program for students to learn software engineering. Their flagship course focuses primarily on Javascript and the associated frameworks used to build real-world web applications.

David Yang and Nimit Maru are the Co-founders of Fullstack Academy. They were part of the Y Combinator summer 2012 class.

", + "Episodes Title": "Training Software Engineers with David Yang and Nimit Maru", + "Episodes Uid": "SED2253937981", + "Episodes Audio File": "ff6f3445318db4e73e122c3df0ed7062.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 764, + "Episodes ID": "e979b6fc-e328-11ea-91a2-1b10f57b2ec2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_05_04_Isolation.mp3", + "Episodes Pubdate Date": "2020-05-04", + "Episodes Summary": "

We are all living in social isolation due to the quarantine from COVID-19. Isolation is changing our habits and our moods, ravaging the economy, and changing how we work. One positive change is that more people have been reconnecting with their friends and family over frequent calls and video chats.

Isolation is not a normal way for humans to live. We are social animals, and we need social interaction. We’ve changed how we use Internet products. There has been an evolution of trends in online shopping, social networking, and video communication software.

Courtland Allen is the founder of Indie Hackers and Anurag Goel is the founder of Render, a new cloud provider. Both Courtland and Anurag are friends of mine, and join this episode to talk about how their lives are changing as a result of social isolation.

", + "Episodes Title": "Isolation with Courtland Allen and Anurag Goel", + "Episodes Uid": "SED9995520396", + "Episodes Audio File": "9a27d77be0b80ab10f5d867c7899d35e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "18k", + "Episodes ID": "267df3ba-e329-11ea-91a2-cb03467c5921", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Kitematic_Edited.mp3", + "Episodes Pubdate Date": "2016-01-05", + "Episodes Summary": "

Kitematic is an open source project built to simplify and streamline using Docker on a Mac or Windows machine. It allows users to get up and running on Docker with a single click, and provides a user interface that makes running and managing Docker files easy. Kitematic was acquired by Docker in March 2015.

Sean Li is the co-founder and Chief Product Officer of Kitematic. He is now working on product design and developer experience at Docker.

", + "Episodes Title": "Simplifying Docker with Sean Li", + "Episodes Uid": "SED4811211457", + "Episodes Audio File": "d02f1a2373d700cfd30711b5691eb0d5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ua", + "Episodes ID": "ea7190c0-e328-11ea-91a2-438f31623000", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_21_CourierMessagingAPI.mp3", + "Episodes Pubdate Date": "2020-02-21", + "Episodes Summary": "

A gig economy application generates lots of notifications. 

There is SMS, mobile phone updates, emails, and native application updates. If you order a ride from Uber, you might receive a text message and a push notification at the same time. If an app overloads the user with notifications, the user might end up annoyed and delete the app from their phone. 

But perhaps all of these notifications are necessary. You would rather get three simultaneous notifications from your food delivery app than fail to get your food on time. If you are the mobile application developer building the food delivery app, what other choice do you have?

At large companies such as Linkedin, there are entire teams devoted to figuring out how to optimize the notifications that they send you. It has a surprisingly large impact on the usability of a mobile application. Troy Goode is the founder of Courier, a company that provides notification optimization.

This might sound like a small, trivial problem. But it actually has a large impact on the usage of apps. And it is not an easy engineering problem. Troy joins the show to talk about the problem that Courier solves and the backend infrastructure that powers it. Courier is built entirely on serverless APIs. This is a great case study in how to build a completely scalable infrastructure product based on serverless tools.

", + "Episodes Title": "Courier with Troy Goode", + "Episodes Uid": "SED5344368591", + "Episodes Audio File": "5cf2fd01f145ed4fbae3bb9ca9173c9e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 249, + "Episodes ID": "178199d4-e329-11ea-91a2-d7776927664c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Industries_Edited.mp3", + "Episodes Pubdate Date": "2016-08-05", + "Episodes Summary": "

Alec Ross worked in the White House as a Senior Policy Advisor to Hillary Clinton. His book Industries of the Future explores the biggest technological opportunities and threats to our society. The industries addressed in his book include robotics, genetics, and cybersecurity.
\nTechnological familiarity is increasingly correlated with an individual’s optimism. Cyberwarfare presents attack vectors that are difficult to insulate against. Arguments about surveillance center disproportionately on governmental surveillance rather than that of the private sector. In our conversation, Alec discusses these topics and others.

", + "Episodes Title": "Industries of the Future with Alec Ross", + "Episodes Uid": "SED7950930239", + "Episodes Audio File": "0e7c0f97f8eef142bb649824b5391e8a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 137, + "Episodes ID": "299963ea-e329-11ea-91a2-2b9d94502c04", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/JS_the_bad_parts_Version_1.mp3", + "Episodes Pubdate Date": "2015-12-09", + "Episodes Summary": "

John K. Paul is an engineering manager and speaker, who has given several talks on Javascript, including JavaScript, the Real Bad Parts. He is the CTO of InRhythm and also an organizer of NYCHTML5.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Javascript: The Bad Parts with John K. Paul", + "Episodes Uid": "SED3581500229", + "Episodes Audio File": "64318b7fec139811813aedd38d36b726.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "14m", + "Episodes ID": "2888ac72-e329-11ea-91a2-9fb5a98b7a6f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Tensorflow_Edited_1.mp3", + "Episodes Pubdate Date": "2015-12-15", + "Episodes Summary": "

TensorFlow is an open source machine learning library intended to bring large-scale, distributed machine learning and deep learning to everyone. Google recently released the framework to the public as a second-generation API, having learned from the successes and failures of DistBelief.

Greg Corrado is a senior research scientist and tech lead at Google, where he focuses on the research areas of machine intelligence, machine perception and natural language processing.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "TensorFlow with Greg Corrado", + "Episodes Uid": "SED7905416726", + "Episodes Audio File": "57c2af20e3fab65c4a52f576288b320e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ad", + "Episodes ID": "e8fd9388-e328-11ea-91a2-bbff53360fe0", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_09_HumaninLoopData.mp3", + "Episodes Pubdate Date": "2020-06-09", + "Episodes Summary": "

The life cycle of data management includes data cleaning, extraction, integration, analysis and exploration, and machine learning models. It would be great if all of this data management could be handled with automation, but unfortunately that is not an option. For most applications, data management requires a human in the loop.

A human in the loop might be responsible for working in a spreadsheet, or labeling data as a mechanical turk, or creating an algorithm for data labeling in Snorkel. Data scientists and data analysts are humans in the loop, studying large data sets.

Aditya Parameswaran is an assistant professor at UC Berkeley. He studies human-in-the-loop data analytics, and he joins the show to talk about the work and the projects that he is focused on, including DataSpread, an alternative to Excel, and OrpheusDB, a relational database versioning system.

", + "Episodes Title": "Human in the Loop Data Analytics with Aditya Parameswaran", + "Episodes Uid": "SED9461453713", + "Episodes Audio File": "d35436d86cab4803f3e2c1b21742944d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "22b", + "Episodes ID": "19faf8ae-e329-11ea-91a2-37611e8c5061", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Schedulers_Edited.mp3", + "Episodes Pubdate Date": "2016-07-07", + "Episodes Summary": "

Scheduling is the method by which work is assigned to resources to complete that work. At the operating system level, this can mean scheduling of threads and processes. At the data center level, this can mean scheduling Hadoop jobs or other workflows that require the orchestration of a network of computers.
\nAdrian Cockcroft worked on scheduling at Sun Microsystems, eBay, and Netflix. In each of these environments, the nature of what was being scheduled was different, but the goals of the scheduling algorithms were analogous–throughput, response time, and cache affinity are relevant in different ways at each layer of the stack.

Adrian is well-known for helping bring Netflix onto Amazon Web Services, and I recommend watching the numerous YouTube videos of Adrian talking about that transformation.

", + "Episodes Title": "Schedulers with Adrian Cockcroft", + "Episodes Uid": "SED1616041688", + "Episodes Audio File": "77b0f1d56e01f3a47eaaa029dd3ac421.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25b", + "Episodes ID": "15d802a8-e329-11ea-91a2-bfde710ff7e3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CoreOS_Edited_2.mp3", + "Episodes Pubdate Date": "2016-08-30", + "Episodes Summary": "

Google’s infrastructure has been the source inspiration for research papers, software projects, and entire companies. Google pioneered the idea that we care less about the individual machines we are running our applications on, and more about the applications themselves.

Containers are the abstraction we use to separate the concerns of the application from those of the underlying hardware. CoreOS is an operating system built with this paradigm shift in mind. In a data center, the main job of the operating system is to be a platform for containers to run smoothly on. Brandon Philips is the CTO of CoreOS and he joins the show to explain what CoreOS does differently to power the applications that get deployed on top of it.

", + "Episodes Title": "CoreOS with Brandon Philips", + "Episodes Uid": "SED1288506392", + "Episodes Audio File": "4d5e46c063c4babf2ad909c42c6c4cdb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ir", + "Episodes ID": "e843438e-e328-11ea-91a2-6faeba9f3ef9", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_17_GitlabCourseware.mp3", + "Episodes Pubdate Date": "2020-08-17", + "Episodes Summary": "

The US Army Cyber School is a training program which trains cyber soldiers and leaders to be adept in cyber military strategy and tactics. In order to teach these skills, the cyber school uses a system they call “courseware as code”, a workflow that allows updates to the curriculum in a reversion-friendly fashion similar to infrastructure-as-code.

Ben Allison teaches at the US Army Cyber School and has put work into developing the training program and ongoing lesson plans. Ben joins the show to talk about how the US Army manages curriculum through courseware as code, and the work he has done to improve this workflow over time.

Ben is also speaking at GitLab Commit 2020, GitLab’s upcoming conference. You can register for GitLab Commit yourself by going to softwareengineeringdaily.com/gitlabcommit.

", + "Episodes Title": "Gitlab Courseware as Code with Ben Allison", + "Episodes Uid": "SED2856568096", + "Episodes Audio File": "9badd885dc387e2fb2ae5ed9b3084faa.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ib", + "Episodes ID": "eb2c93ca-e328-11ea-91a2-8386f0f8d0d6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_16_Snyk.mp3", + "Episodes Pubdate Date": "2019-12-16", + "Episodes Summary": "

The software supply chain includes cloud infrastructure, on-prem proprietary solutions, APIs, programming languages, networking products, and open source software. 

Each of these software categories has its own security vulnerabilities, and each category has tools that can help protect a company from attackers that are trying to exploit known vulnerabilities. As open source software has grown in popularity, it has turned into an enormous potential attack surface that is difficult to protect.

Snyk is a company that builds security tools for companies that are consuming open source. Guy Podjarny is the CEO of Snyk, and he joins the show to discuss the security vulnerabilities of open source projects, and how his business works. Guy was previously the CTO of Akamai, so he has significant experience in technical leadership. He also is the host of the podcast The Secure Developer, which I recommend for anyone who is interested in technical interviews about security topics.

", + "Episodes Title": "Snyk: Open Source Security with Guy Podjarny", + "Episodes Uid": "SED5578251227", + "Episodes Audio File": "bdc391c4309794e855a8e899c7794ef5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1x5", + "Episodes ID": "1de61908-e329-11ea-91a2-3b0bd8e8c254", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Eventhubs_Edited.mp3", + "Episodes Pubdate Date": "2016-04-26", + "Episodes Summary": "

Apache Kafka has become the most popular open-source solution for persistent replicated messaging in the Hadoop ecosystem. But some software engineers who are working with “big data” don’t want to deal with the configuration and set up of Kafka.

One way to side step this problem is to go with a managed solution, like Microsoft Azure Event Hubs.

Dan Rosanova is today’s guest. He joins us to discuss persistent replicated messaging, and the features that Azure Event Hubs provide. This is an interesting discussion about distributed pub sub messaging, and we also get into a great conversation about platform as a service versus open source software, and the future of cloud software.

", + "Episodes Title": "Azure Event Hubs and Kafka with Dan Rosanova", + "Episodes Uid": "SED1490855347", + "Episodes Audio File": "e056be69f47e1b58fe5f9aec0f0fff8f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1w5", + "Episodes ID": "1e158ed6-e329-11ea-91a2-ffa1b567eb46", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Honeybadger_Edited.mp3", + "Episodes Pubdate Date": "2016-04-21", + "Episodes Summary": "

Applications crash, and engineers need to be able to quickly find the root cause of a crash. Apps have become distributed, and debugging workflows have changed. Developers need better tools to identify and troubleshoot problems with their apps.

Ben Curtis joins us today to discuss Honeybadger, an exception and monitoring tool for web applications. We discuss how software tools can be used to detect problems faster and improve the debugging workflow.

", + "Episodes Title": "Debugging Your Crashes with Ben Curtis", + "Episodes Uid": "SED7433455278", + "Episodes Audio File": "176f027926ec529e076516c6670bb3f6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1qy", + "Episodes ID": "20642e68-e329-11ea-91a2-6705b2a6551d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Might_Edited_2.mp3", + "Episodes Pubdate Date": "2016-03-17", + "Episodes Summary": "

Software engineering is a deterministic field. We write lines of code, and feed data into that code, expecting to get a certain answer. Computing is deterministic because humans developed it–we understand computers from top to bottom. The same cannot be said about biology.

Matt Might is an associate professor with a PhD in computer science. When his son was diagnosed with an extremely rare illness, he was confronted with the uncertainties of human biology. In this episode, we discuss Matt’s quest to solve the puzzle of his son’s disease–computer science meets genetics, on this episode of Software Engineering Daily.

", + "Episodes Title": "Using Software to Discover Rare Diseases with Matt Might", + "Episodes Uid": "SED9235338938", + "Episodes Audio File": "86d9647d483e944429d76adf69a11d6b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6mv", + "Episodes ID": "eadc306a-e328-11ea-91a2-a3e6d9af777b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_22_DFINITY.mp3", + "Episodes Pubdate Date": "2020-01-22", + "Episodes Summary": "

If the Internet was reimagined with the software and hardware infrastructure we have today, what would it look like?

That is the question that DFINITY is working on answering. DFINITY’s goal is to build a decentralized, secure Internet computer. DFINITY takes concepts from the cryptocurrency world, but it is focused on computation, not financial products. DFINITY can be thought of as a decentralized cloud provider, with redundancy and scalability properties that are achieved by operating on data centers across the world.

DFINITY wants to host web applications such as the ones that we use today on centralized servers. A developer who wants to run their application on DFINITY compiles their code to WebAssembly and deploys it to the DFINITY decentralized runtime. Transactions across DFINITY applications are processed through a collateralized proof-of-stake system to ensure reliable, decentralized computation.

DFINITY is an ambitious project, and it would seem nearly impossible to bring to market if not for the quality of the team. DFINITY has hired Andreas Rossburg, a co-designer of WebAssembly, as well as talented engineers across security, web development, and backend infrastructure.

Dominic Williams is the president and chief scientist of DFINITY, and he joins the show to talk about the vision for DFINITY and the roadmap to making it a reality.

", + "Episodes Title": "DFINITY: The Internet Computer with Dominic Williams", + "Episodes Uid": "SED2379953918", + "Episodes Audio File": "4e6f4df9a2fb6648fb09c7010f91a0a5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "36a", + "Episodes ID": "f5def6e6-e328-11ea-91a2-8ff3889e7791", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/VladZamfir.mp3", + "Episodes Pubdate Date": "2017-10-28", + "Episodes Summary": "

A cryptocurrency has a distributed ledger called a blockchain. The blockchain keeps track of every transaction that occurs across the cryptocurrency. This blockchain must stay up-to-date and verified–which requires someone in the network to do that validation.

Bitcoin and Ethereum use the proof-of-work algorithm. Miners do computational work to validate the legitimacy of transactions across the network, and in return they are given cryptocurrency as a reward for that computational work.

In the future, cryptocurrencies could move towards a proof-of-stake model. If you own a significant amount of cryptocurrency, you have incentive to keep the validity of the blockchain up to date. Proof-of-stake algorithms can be significantly less energy intensive.

Vlad Zamfir is a researcher for the Ethereum Foundation, and he joins Haseeb Qureshi for a conversation about cryptoeconomics. This is an in-depth conversation between two active blockchain developers. We hope you enjoy it.

You can send us feedback on the show by emailing me jeff@softwareengineeringdaily.com or joining us on the Slack channel at softwareengineeringdaily.com/slack.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cryptoeconomics with Vlad Zamfir", + "Episodes Uid": "SED3219539775", + "Episodes Audio File": "1226d1c90b153c0643534efb5e0d2e6f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 140, + "Episodes ID": "28f68a44-e329-11ea-91a2-e7a151cee871", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/geekwire_1.mp3", + "Episodes Pubdate Date": "2015-12-12", + "Episodes Summary": "

Todd Bishop from The GeekWire Podcast recently interviewed Jeff for a discussion on various topics including programming languages, coding bootcamps and the philosophical question of whether programming is an art or a science.

Thanks to GeekWire for the opportunity! You can find the show and more at Geekwire: http://www.geekwire.com/2015/is-software-development-art-or-science-geekwire-podcast-with-software-engineering-daily/

", + "Episodes Title": "GeekWire Podcast with Software Engineering Daily", + "Episodes Uid": "SED8155144040", + "Episodes Audio File": "ad8e87d66c9eb37bc3459035f6b0d67d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24j", + "Episodes ID": "17796606-e329-11ea-91a2-1ff73478cd76", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/You_Are_Not_A_Commodity.mp3", + "Episodes Pubdate Date": "2016-08-07", + "Episodes Summary": "

Most episodes of Software Engineering Daily are interviews with an expert about a technical software concept. Occasionally I write editorials, and also record them as a podcast.

The first editorial was about 10 Philosophies for Engineers, the second was about how poker relates to software engineering, and the third was about music and software engineering.

Today’s episode is called “You Are Not A Commodity”.

Since it is a departure from the normal format, I am releasing it on a weekend, and there are no ads on this episode. If you don’t like this episode — don’t worry. On Monday, Software Engineering Daily will be back to the usual highly technical rigor. In any case — please send your feedback on Twitter or email.

You Are Not A Commodity

Software engineers are often trapped in careers that consist entirely of software maintenance rather than building new products.

This post:

During the industrial revolution people began working on assembly lines.

At the assembly line, workers were given narrow roles. The assembly line is a resilient, consistent tool for manufacturing because the roles of each worker are so well defined that the worker can be easily replaced.

Assembly line workers are so easily replaced as to effectively be a commodity — a raw good to be bought and used up.

For the worker, becoming a commodity was unpleasant. But there were not good alternatives to working on an assembly line. You could not simply quit the assembly line and go start your own.


\nIndividual workers suffered, but society progressed quickly because industrialists could leverage the commodity workers to have more predictable output.

This method of production continued into the the information age.

Early computer systems were hard to operate. Individuals did not have much leverage. Teams of people needed to be closely managed to accomplish significant tasks.

Today, computer systems are easier to operate. Individual engineers can build lifestyle businesses. Small teams can build products as big as WhatsApp. Everyone has more leverage — not just industrialists who are in charge of assembly lines.

Most software engineers take a career path that gives them as much leverage as the commodity workers of the assembly line. We conform ourselves to the unpleasant tasks that are needed by large corporations.

Why should I care? Is this bad?

If you take one thing away from this post, make it the following: it is now easy to build your own assembly line.

The economics of the big company do not reward the lower level workers. Today, it is easy for a skilled engineer to opt out of the poorly compensating corporate machinery.

20 years ago, the tools within a large software corporation were much more sophisticated than anything you could buy as an individual.

Then Amazon Web Services reduced the cost of server provisioning and management from $50,000 for a machine to essentially free.

The excellent free infrastructure provided by AWS led to excellent free software like Dropbox, Trello, and Slack. These cheap tools integrate with each other and empower the individual to be massively productive.

SaaS tools get combined with each other and built into even better tools. The quality of available software compounds at a staggering rate.

Cloud computing triggered such a massive improvement in public software that individuals and small teams can build a tech stack that often works more effectively than that of a big corporation.

Big corporations are tightly coupled to their tools, and cannot take advantage of this rapidly compounding software quality. Outside of a big corporation, you are free to mix and match tools as you see fit.

Software tools are the means of production, the equivalent of the assembly lines of 1900s industrialists, and access to these means of production have become decentralized.

In fact, the entire economy has become decentralized.

Not just means of production but distribution, contracting, payments, access to domain expertise, and every other aspect of business. The advantages of big centralized corporations are now available to individuals and small teams.

Fiverr is one example of a service provider that an individual or small team can use for leverage. Fiverr contractors can provide cheap help with accounting, WordPress, audio and video editing, marketing, and other supplementary work that big companies hire full-time employees to do.

A large corporation needs recruiters and hiring managers employed to vet potential employees. Instead of the time-consuming interview process, Fiverr’s reputation system means that the work of candidates speaks for itself. Interviewing is a formality.


\nFiverr is useful for tasks that are not complicated, but require focus and consistency. Upwork, a similar service, can be used for more complex tasks, like software development. These services fulfill the dream that was believed about offshoring software development in the 1990’s — high quality, cheap outsourcing.

Fiverr and Upwork put downward pressure on the cost of contractors, but software businesses also need full-time workers. Building a full-time engineering workforce has also become cheaper.

This sounds counterintuitive to anyone who has heard of the “peak talent war” of tech, but each individual engineer has so much leverage today that you need dramatically fewer engineers to ship good software. You also don’t need to pay for real estate to house those engineers.

In the past, a team of software engineers needed a physical place to work together in. That is no longer the case. Docker, TopTal, and Hashicorp are among the companies that have moved to remote work, enabled by Slack and other collaboration tools.

Remote companies report increased transparency and improved communication. Remote employees must leave a trail of finished work to let themselves be audited — which is not difficult for employees who are actually getting work done. Chat logs and github commits do not lie.

At a large company, engineering productivity is reduced by having to interface with project managers and business development people.

Small companies benefit from the fact that engineers have to understand the big picture — business, design, sales, and product development. Engineering manager Fred George’s concept of Programmer Anarchy takes this to the extreme.

The success of Programmer Anarchy indicates higher leverage among engineers. The role of engineer can subsume all other roles.

Programmer Anarchy works today because the tools are better and the practice of software engineering is more widely understood. Engineers don’t have to spend as much time writing boilerplate code, so the leftover time can be spent thinking about the product at a higher level — which yields business value.


\nUnderstand this: the leverage of the individual engineer is big — much bigger than it has ever been. The leverage of the small team is massive.

If you are building a business alone or with a small team, the classic advice is to “make something people want” or “live in the future and build what seems interesting”.

This is good advice for the brainstorming phase of building products, but many engineers have never built a prototype. Engineers who have done maintenance for their whole career can’t imagine how to go from an idea to a usable product.

If you have spent most of your career at a large corporation, you might be handicapped by a reliance on internal tooling and workflows. If you want to build a product end-to-end, you have to devote some time to getting decent at every area of the stack.

You have to learn to prototype, which means building new programs from nothing. This is more of an emotional and psychological journey than a technical challenge.

We all remember the pleasure of building software from scratch, whether it was a simple game or a calculator app. Why do we ever stop building new stuff? Because our corporate software jobs normalize the idea of software maintenance.

If you have just escaped a corporate job, you can start with 1–2 months of re-skilling. You probably have some money saved up, and it might even be worth going through a coding boot camp.

Boot camps like Hack Reactor are renowned for their ability to instill engineers with the skills and the necessary workflows to build projects alone.

Even if you have a computer science degree, there is no shame in going to a coding boot camp. Universities teach theory, boot camps teach execution.

Whether you attend a boot camp or lock yourself in your apartment with a Pluralsight subscription, the re-skilling process can iron out the sad past life of the software maintenance engineer, allowing for a rediscovery of the creative joy that probably made you fall in love with programming in the first place.

This means getting away from the thick, industrial languages like Java and C#, and going deep on a set of tools that allow for rapid prototyping, like React and NodeJS or Ruby on Rails.

An engineer who is interested in data science and machine learning can spend time learning TensorFlow or Spark — there are countless tutorials online.


\nBuilding an entire prototype and deploying it to Digital Ocean or Heroku is a satisfying experience — especially after spending several years on the software assembly line, understanding only small parts of an application.

The first time you type in the URL of a webapp that you built and deployed entirely yourself will provide a rush that no six-figure programming job can provide.

With enough practice, building your own software becomes easy. The challenge then becomes what to build.

After acquiring fresh skills and learning to prototype, it is easier to dream up new product ideas without the self-doubt that you won’t be able to bring such a product to market.

Once you have the requisite skills to build a software product, what do you build?

Much has been written about the brainstorming process. Paul Graham essays and books like The Lean Startup are useful guides to thinking up an idea for software that generates money.

After spending a long time in a large corporation, your ability to think up fresh ideas might have become weak. As a programmer trying to think up new ideas, it is easy to become discouraged and think that everything has been invented already.

One strategy for overcoming this mental atrophy is to look at the giant markets that would be too big to capture even if all of the programmers in the world pursued them at once.

“Machine learning + X” is one of the safest routes to take if you are building a software business and don’t know where to begin. As futurist Kevin Kelly says, “The business plans of the next 10,000 startups are easy to forecast: Take X and add AI.”

Every business needs machine learning applications in the same way that every business needed a web site in the 90’s. At the same time, most developers are afraid of machine learning because it sounds intimidating.

When developers try out the available machine learning tools, they find scikit-learn to be as accommodating as Ruby on Rails is for web development.

Even if you build a machine learning product that nobody needs, you will have to learn machine learning in order to do that. If your first product fails, you might be able to reuse some of the code in your next machine learning product.

Hardware is another field with wide opportunity. Like machine learning, hardware also sounds harder than it is (“hard” is even in the name).

Just as Spark and scikit-learn are simplifying machine learning, cheap hardware like Tessel and friendly software frameworks like Johnny-Five are simplifying hardware prototyping.

IoT is the place to start for new hardware developers. Every major cloud provider and chip producer is investing heavily in IoT. Since giant companies are competing to provide the best IoT platform, individual developers can take advantage of that competition.

For the developer, everything is cheap. Companies like GE, Amazon, and Microsoft are fighting to capture market share, and they are willing to lose plenty of money bringing developers onto their platform.

Common customers for IoT products are factories, farms, warehouses, and other industrial businesses. These sectors also have huge piles of money to spend, and they are becoming more tech-savvy and willing to experiment with new hardware.

Regardless of what product you build, every enterprising software engineer should keep in mind one fundamental trend: the biggest pair of economic forces working in your favor are cloud computing on the supply side and small devices on the demand side.

Small devices like mobile phones and IoT need new, unique applications. Customers will pay money for these. Cloud computing means that providing those applications to the end user is cheap.

This trend will impact whatever area of technology you decide to work on in some way.

In developing countries, the demand for unique smartphone apps is even more acute than it is in the developed world because consumers in developing countries often do not have a laptop or desktop computer. The only computer they have is a smart phone.

Today, many developing countries have poor connectivity, which makes the demands of consumers different from developed countries. These places are less saturated with technologists, so they are ripe for people looking to study the local markets and understand the pain points of consumers.

There are plenty of other burgeoning sectors — the gig economy, virtual reality, Docker, cryptocurrencies. After studying any one of these sectors in detail, it becomes clear how much technological growth can be realized in the next few years, and how few people are putting themselves in a position to capture it.

The hardest battle to fight here is understanding that you should build something. Once you internalize that fact and acquire the necessary skills to prototype, the process of building is a fun exploration, even if you fail along the way.

Now that we have discussed how to build an assembly line, let’s address some counterarguments that favor being a commodity employee of a large corporation.

The compensation counterargument: corporations pay lots of money


\nThe average employee realizes a small fraction of the value created by her work.

Most of the money goes to the people who created the assembly line, not the people who maintain it and build on top of it. Clearly, individuals who create an assembly line are rewarded more handsomely.

The loyalty counterargument: someone has to do this work!

Employees often feel a sense of guilt when they leave a large company. Their work is so important to the company’s health — how will the company run without it?

If your work is so important to the company, that probably means you could go to your manager right now and ask for the biggest raise that is justifiable given the revenue generated by your work. If they don’t give you the raise, that means they won’t have trouble replacing you.

If the company does give you a raise, that implies that the company could have calculated that your work was more important than your compensation implied — in which case the company was deliberately paying you less than it could afford. This doesn’t sound like a relationship where “loyalty” should play a major role in our career calculus.

Your relationship to a big company is firstly transactional. The company needs to pay you the minimum and extract the maximum. There is room for feelings of loyalty only at the margins of this relationship.

The stability counterargument: large corporations are safe

Corporations present a career ladder that can appeal to a student who progressed comfortably through the linear path of high school and college, where success was simple to plot.

This straight path seems quite comfortable. Do the work you are assigned and you will naturally rise through the ranks. In the average case, life is good!

The average case always looks good for strong engineer. If you are a good engineer, your downside risk is capped in most conceivable futures.

It is almost impossible to imagine a world in which engineers are not in high demand. In the hypothetical scenario where a good engineer is not employable, it is likely that something will have gone drastically wrong with the economy.

This fact negates the idea that patiently saving for the future is “safe”. Which financial instrument could you keep your money in that would insulate that money from a total economic collapse? Even if you have $200,000 in guns, gold, and bitcoin, will you even have the self-sufficiency to know how to properly manage those assets in a time of economic collapse?

Assuming the world economy continues the way it is going, the path of the corporate ladder is much riskier than starting something on your own. If you start something on your own and fail, you can always return to a large corporation, probably with improved skills.

The safer investment is to train yourself with the ability to invent and be independent.

The leverage counterargument: corporate infrastructure empowers me


\nInnovations made by internal employees

Google, Amazon, and Facebook retain their best employees by giving them freedom to invent. The employees who built AWS, or the Like button, or the HoloLens escaped their commodity status by building something that differentiated them so much as to become a lynchpin within the company.

Inventing from within a large organization is the perfect strategy for someone who is stuck at a company on an H1-B, or who is working off student load debt, or who has a family situation that prevents them from quitting their job.

If you aren’t restricted by immigration constraints or financial constraints, you have much more to gain by building something on your own outside of a company. It raises the stakes and forces you to overcome your fears.

When you invent a product on your own, the best case scenario is quite appealing. You get to capture 100% of the product’s value and you maintain complete creative control. Neither of these are guaranteed when inventing at a big company.

The mentorship counterargument: a corporation is a great place to learn

Corporations can be a great place to learn how to do highly structured work. You are assigned tasks, you learn how to use tools like git, you learn how to sit through meetings and talk to co-workers.

Reviewing code from other co-workers can be educational, and teach you how to improve the efficiency and readability of your own code. The corporation will impose reasonably high standards on your work.

The problem with “mentorship” at a big corporation is that it brainwashes you in the same ways that it has brainwashed the people who will be your mentors.

As an inexperienced employee, your work is likely to be centered around software maintenance. The company will pitch it to you as fresh and exciting because they see you as naive. But you won’t be building a new product where you have creative control and true responsibility.

The hardest part of building a new product is deciding that you are going to build a new product, and following through with that decision. Corporate mentorship is not going to focus on this.

If your long-term goal is to build new products, avoid the farce of corporate mentorship. If your goal is a career of software maintenance, then commence the brainwashing.

Building new software is the perfect activity for someone who likes art, science, business, or adrenaline.

Other activities that provide a similar emotional high include drugs, video games, sex, gambling, browsing Facebook, writing music, painting a picture, international diplomacy, raising children, and skydiving.

Humans get habituated to most of these activities and have to constantly raise the stakes. We need to gamble for more money. We need more intense drugs and more immersive video games.

When we build software companies, the stakes automatically get raised over time. As users grow, our financial swings get bigger. Users who love the products we build give us praise that is more meaningful than the Likes and comments on Facebook. And the intellectual challenge is constantly morphing and presenting new problems to solve.

Inventing new software is sustainable, rewarding, and fun. It is an adventure!

Many engineers work a job where they feel like a replaceable commodity. They spend several hours a day pondering their existence and doubting their self-worth. Escape this trap — build something!

", + "Episodes Title": "You Are Not A Commodity", + "Episodes Uid": "SED7024108817", + "Episodes Audio File": "ebf4c819a7b9629be37d1164cd5975b6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 325, + "Episodes ID": "f672abe8-e328-11ea-91a2-07ea308b1b6a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/MoatAnalytics.mp3", + "Episodes Pubdate Date": "2017-09-16", + "Episodes Summary": "

Moat is one of the most successful advertising technology companies in history. After building a business from measurement of ad impressions, Moat was sold to Oracle for $850 million.

Advertising powers the free content on the Internet. Measurement makes it easier for publishers to monetize their content. At Software Engineering Daily, we know this from firsthand experience. The podcast ecosystem has barely any ability to measure success–and that can make it hard to entice advertisers. In podcasting, it is very difficult to understand if an advertising campaign is a success.

This illustrates why Moat is important. Improving the analytics on advertising helps publishers, brands, ad agencies, and adtech companies decide how to allocate their capital.

Why is it hard to measure advertising success? Why is this a difficult engineering problem? Because there are so many players in the space with conflicting incentives.

A brand wants to show ads to people who will buy a product. A publisher wants to display an ad that will maximize revenue. Adtech companies and ad agencies want to take the biggest cut possible from the transactions between brands and publishers. In the midst of all of this, fraudulent traffic providers offer cheap services that drain money from anyone who is not keeping a close eye on their deal flow.

In this fog of war, Moat’s goal is to provide transparency where possible. Moat CEO Jonah Goodhart joins this episode to talk about advertising analytics, viewability, and fraud.

If you like this episode, we have done many other shows about adtech and advertising fraud. You can check out our back catalog by going to softwareengineeringdaily.com or by downloading the Software Engineering Daily app for iOS, where you can listen to all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that.

", + "Episodes Title": "Advertising Analytics with Jonah Goodhart", + "Episodes Uid": "SED8800785384", + "Episodes Audio File": "35d5073aa8be7732bb59302ef2d491b6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24q", + "Episodes ID": "174bcffc-e329-11ea-91a2-978f378fa3b8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/prometheusbrian_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-08-10", + "Episodes Summary": "

Prometheus is a tool for monitoring our distributed applications. It allows us to focus on the services we are deploying rather than the individual machines that make up instances of that service.

The monitoring service itself is a portion of a distributed system that is treated differently than the services we are monitoring. We don’t want to use a consensus-based tool like Zookeeper or Consul because we can’t afford the strong consistency.

Brian Brazil’s company Robust Perception is built around Prometheus, and he joins the show to discuss why and how to use Prometheus.

", + "Episodes Title": "Prometheus Monitoring with Brian Brazil", + "Episodes Uid": "SED8611057797", + "Episodes Audio File": "0be9fe6082aee60302f8a439c2577d5e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "20f", + "Episodes ID": "1b5d4a30-e329-11ea-91a2-17099fac69d1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Music.mp3", + "Episodes Pubdate Date": "2016-06-11", + "Episodes Summary": "

Most episodes of Software Engineering Daily are interviews with an expert about a technical software concept. Over the past year I have done a few experiments that are more editorial in nature, and both were very popular. The first editorial was about 10 Philosophies for Engineers, and the second was about how poker relates to software engineering.

Today’s episode is an editorial about the creative process of writing computer music, and how it relates to software engineering.

Since it is a departure from the normal format, I am releasing it on a weekend, and there are no ads on this episode. If you don’t like this episode — don’t worry. On Monday, Software Engineering Daily will be back to the usual highly technical rigor. In any case — please send your feedback on Twitter or email.

A year ago, I was working at Amazon as a software engineer. Much of my spare time was spent writing music on the computer. I would wake up at 6 AM, work on music for three hours, and then walk to work through downtown Seattle.

The great tragedy of working at any giant tech company is that most employees are completing menial tasks that make the company millions of dollars and make the employee a small fraction of that financial windfall.

In the past, these economics made sense for the employee. The employer used to be a source of leverage for talented workers. Today, our tools are so cheap and powerful that we can succeed on our own, without a giant corporation. Unfortunately, this is such a recent development that most employees remain trapped within the story of corporatism. Employees dutifully believe that the corporation is doing them a favor.

The last song I wrote while I was at Amazon is called Zeroes. It is about people who are not aware of the fact that they have much more power than corporations want them to believe.

Writing music is similar to writing software. The digital audio workstations that music producers use are similar to IDEs that we use to step through a debugger, or detect errors in code. Just as an IDE will help you organize your code and manage your abstractions, a digital audio workstation can be used to coordinate instruments. The workstation can tell you what keys to play in what order, so you don’t need to know anything about music theory.

Despite all of this help, the music software still doesn’t write the song for you. Much like the human-machine teams that currently dominate competitive chess, the best music today comes from the musicians who are best able to work in harmony with the most sophisticated technology. This has always been the case — from The Beatles to Max Martin to Skrillex.

What the human brings to the table in human-machine music creation is an understanding of contemporary tastes. This is why I listen to pop music. Top 40 radio stations and Spotify playlists are not perfectly democratic, but they are close enough. I pay attention to the trends of the most popular music, and try to replicate them.

This next song was written because I was copying the bass lines that became popular from the Iggy Azalea song Fancy, which was #1 for seven weeks straight in the Summer of 2014. Even after trying to copy the bass line, I ended up with a very different song than Fancy.

Open source allows software quality levels to reach new heights. With open source, new software builds compounding interest on previously written software. The software spreads and replicates freely around the internet thanks to open repositories that new users can pull from.

In music, this easy replication of information has led to a sampling revolution. Sampling is the act of cutting a snippet of sound from a song, or a TV show, or simply any random noise that you find interesting, and turning that snippet of sound into its own instrument.

In 2009, I was studying hip hop production techniques. On uTorrent, I found a download of hip hop acapellas — samples of rappers rapping without instrumentals. I stitched some of these acapellas together and made a lyrical sample with 50 Cent, Eminem, and Nas. Underneath that vocal, I sliced up a sample from 24-Carat Black, a soul and funk band from 1970s that has been sampled by lots of hip hop artists.

As a warning to sensitive listeners, these lyrics contain some harsh and sexist language, and do not represent my views as a podcaster.

This next song is called Chicago, written when I was in Chicago at my first job out of college. The creation of that song was driven more by raw emotion than a logical approach, or a specific musical concept.

I was working as a software engineer at an options trading company called PEAK6. The people at the company had fascinating, extreme personalities and brutal honesty was encouraged more than anywhere else I have worked.

At PEAK6, building options trading software that could directly translate into profits for the company, I also had the feeling that if I did something important that made the company a lot of money, I would be compensated fairly. In this sense, a trading company can be more of a meritocracy than other tech companies.

Working at a trading company, if you build a software feature for the traders in your company, you can walk over to the traders and ask them how much money it is making them. If they say it has increased their profits by 10%, it is very straightforward to ask your boss for a raise of at LEAST 10%. In contrast, at most tech companies, if you build a tool that improves productivity for your coworkers or your customers, it is often harder to quantify whether you deserve a raise based on building that software. Furthermore, at big tech companies there is so much office politics, and so many rules of propriety and servility and respect of your superiors — if you do something that you think is impressive, but it doesn’t positively impact your manager, that action might actually have negative consequences for you as an employee.

On the trading floor, the atmosphere of healthy debate, brutal honesty, and lots of money flying around reminded me of my roots as a poker player, and in that sense I felt at home. In college, I was so obsessed with the intersection of finance and technology that I wrote a piece of fiction about an artificial intelligence that gets built at a hedge fund. The AI gets so smart that it eventually divests itself from the hedge fund and starts its own company, calling itself simply “Bank”.

This next song is about that financial AI that awakens within the hedge fund — the song is called BANK.

Most software engineers have written a game at some point in their career. I spent much of my time in college thinking about games that reflected the absurd financial fluctuations that I experienced as a poker player. The greatest games provide the player with a sense of drama. A game should be designed to be able to turn your stomach or fill you with elation and adrenaline.

One game I worked on in college with a few friends is called MoonStocks. I built it with a few friends — Josh Stewart and Pong Tam — in this game, you can buy and sell fictional stocks that fluctuate in price based on Fourier transforms of songs I wrote. On the Android Play Store, you can download MoonStocks if you are interested.

MoonStocks gave me great pleasure, because it allowed me to combine my niche interests of games, finance, music, storytelling, and programming. This is a lesson in creativity that is preached often these days in our long-tail economy: if you can’t be a 10,000 hour master of one specific thing, try to master the intersection of a few niche topics. The more unusual the topics that you pursue, the greater a chance you have at developing a deeper understanding than anyone else.

Another game I built in college was called “RatMarket”. The setting of the game is a post-apocalyptic world where the only organisms left are rats and humans. Rat meat has become the only commodity that is traded in the world, and human arbitrageurs create bizarre financial instruments out of the rat meat commodity trading market. This was yet another dead-end project, but after working on it for awhile, I was so engrossed that I wrote a song based on it. So I hope you enjoy this next song, “RatMarket”.

Absurdity is at the heart of the projects I work on. Playing with absurd concepts lets you stay unpredictable as a creator. When you combine absurdity with a relentless work ethic, you end up exploring more ideas with more tenacity than anyone else. People who respond to absurdity with shame and condemnation are repressed. They have never discovered the utility of the absurd because they have never experimented outside of local maxima of what makes sense.

This is not to say that absurdity should be adopted as a way of life. Absurdity taken too far is embarrassing and unproductive. A pleasant, intellectual conversation with a hint of absurd humor can be ruined by a sarcastic person, a drunk, or a stoner who takes the absurdity too far.

Absurdity is a tool to explore the edges of what has not been clearly delineated by science and reason. It is with a taste for the absurd that Airbnb was dreamed up. I’ve seen enough videos of Airbnb CEO Brian Chesky telling the Airbnb story to know that absurdity is deeply ingrained in the DNA of the company. How else would you come to the conclusion that having strangers sleeping on air beds in your apartment would be a billion dollar business? Not to mention the cereal box fundraising story.

When I try to reason about how intelligent machines will think about the world, my sense of logic fails me. When we are speculating about how machines will think, we instinctively turn to the way that humans think, and try to imagine robot cognition relative to the human model of cognition. This is almost certainly wrong. But still, this topic inevitably comes up in conversation.

Vacillating between the ideas of the serious, and the absurd, the next two songs explore two sides of how I speculate about the evolving artificial intelligence. The first song is simply called Robots, and it represents the absurdly alien sense of how robots might come online with self-awareness. The second song, Roger the Robot Janitor, explores the human-relativistic view of how robots might think to themselves.

Roger the Robot Janitor is more about humans than it is about robots. Most of us have had a job that we don’t like. Roger has been designed with cutting edge artificial intelligence technology, and his job is to clean toilets at an elementary school.

If you are a well-educated American listening to this, you were probably raised with the belief that you could do anything. You jumped through all of the right hoops, you went to college, you got a high paying job. And yet, somewhere along the way, the ideals that you felt growing up turned into a desperation in the pit of your stomach. It seems like something happened along the way and you are no longer looking at the world as an opportunity, but as something to insulate yourself from and relentlessly hedge against.

It is an all-American seduction that many of the best and brightest computer scientists are seduced from college into crappy, dead-end jobs at giant software companies. They are dead end jobs because they seduce you into a mindset that is not true. The mindset is that you need a giant corporation to survive, and that it is noble and validating to go work at a job with minimal creativity and maximal servility.

In this sense, we are all Roger the Robot Janitor. We have all woken up to realize we have been programmed with the peculiar desire to keep ourselves from doing anything substantial, for fear of disrupting the safe but blase life that we have established for ourselves.

If you have had this realization, you have either suppressed it, or experienced a dramatic internal transformation. Or — if you are like me when I was at Amazon — you are experiencing cognitive dissonance. You are suppressing yourself from acting out because you are in preparation mode. You are preparing to escape your cloistered environment, saving up money and willpower.

You are on the Career Track, but soon you will be on your own. And there is great drama in this moment.

In the Summer of 2010, the cassette-to-iPod connecting cable in my car broke, and I could no longer play podcasts and music while I was in the car. On the commute to and from my Summer internship, I had an hour and a half of time driving. So I started listening to radio, and during this time I discovered the beauty of contemporary pop music.

The melodies in pop music are extremely simple, and this makes songwriting extremely simple. In software engineering, when you have the simplest abstractions, programming is exhilarating. Studying pop music was like studying functional programming — the abstractions make creativity unexpectedly easy. Also, both pop music and functional programming have rabid fan bases.

In order to fully adopt the mindset of a pop musician, I had to write a song about love and relationships and heartbreak, because almost every pop song is about romance. During this time, I was becoming so obsessed with pop music that I decided at some point I was going to become a pop music producer. With this in mind, I needed to learn to collaborate, so I convinced my friend Genevieve to sing what I wrote. The song is called “Letdown”.

At this point, I have talked through an hour’s worth of songs. This topic is too self-indulgent and far removed from the core idea of Software Engineering Daily to go much further today, but if you listened this far I sincerely thank you.

I always want to know what you think of this show. Send me an email at softwareengineeringdaily@gmail.com, or tweet at me. It is a huge privilege to have people who listen to this show — so let me know what you want to hear about.

I’m going to close with a song that I wrote for my cat Scout. The song is called Scout. Thanks again for listening.

", + "Episodes Title": "Music", + "Episodes Uid": "SED2806829560", + "Episodes Audio File": "cfc6fe1957f358777bf6977b6be2ec86.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1x8", + "Episodes ID": "1d039042-e329-11ea-91a2-2b6ab48c545c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/azure_stream_final.mp3", + "Episodes Pubdate Date": "2016-05-12", + "Episodes Summary": "

Microsoft has built a suite of technologies on top of its Azure infrastructure as a service.

Today, we discuss Azure Stream Analytics, a real-time event processing engine developed at Microsoft. Azure Streaming allows for constant querying of incoming data streams, and my guest Santosh Balasubramanian discusses Azure and the movement from batch processing to stream processing.

", + "Episodes Title": "Azure Stream Analytics with Santosh Balasubramanian", + "Episodes Uid": "SED9258996663", + "Episodes Audio File": "503c813265372f3e5dd2473c60e7ae1b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23y", + "Episodes ID": "18891514-e329-11ea-91a2-777cd87236f8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/github_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-07-27", + "Episodes Summary": "

github has grown to have 10 million users and 30 million repositories. Getting to this scale has required innovation in many places–github has significantly altered the code for git itself, and has built unique infrastructure and written low level code to architect for git repository management at scale.

Despite the need for cutting-edge technologies to support github, the development culture at github values tried and true technologies, and today’s guest Sam Lambert explains the value of maintaining a Rails monolith as the frontend of github, and the other battle-tested tools that github uses.

", + "Episodes Title": "Scaling github with Sam Lambert", + "Episodes Uid": "SED3016142504", + "Episodes Audio File": "66283f94c39e89b05abca9bbb8c18bb6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2cd", + "Episodes ID": "0ef8168a-e329-11ea-91a2-b3b09a63b61c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/how_sed_works_edited.mp3", + "Episodes Pubdate Date": "2016-12-08", + "Episodes Summary": "

Software Engineering Daily was started a year and a half ago, based on what I learned from my podcasting experience on Software Engineering Radio. Last week, I interviewed Robert Blumen, the editor of Software Engineering Radio, about how that podcast is produced. In today’s episode, Robert interviews me about this podcast.

If you are thinking about starting a podcast about software engineering, this podcast will be useful to you. We discuss the processes behind preparing for a show, how to conduct an interview, why people listen to podcasts, and advertisers. I also give some of the history behind Software Engineering Daily–why I started it and what my goals are.

", + "Episodes Title": "How Software Engineering Daily Works", + "Episodes Uid": "SED6446361250", + "Episodes Audio File": "ee59f98c628714899a1e490a9614fed0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "35h", + "Episodes ID": "f5fb499a-e328-11ea-91a2-3f9b4e4648f3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SmartContractSecurity.mp3", + "Episodes Pubdate Date": "2017-10-20", + "Episodes Summary": "

A smart contract is a program that allows for financial transactions. Smart contracts are usually associated with the Ethereum platform, which has a language called Solidity that makes it easy to program smart contracts. Someday, we will have smart contracts issuing insurance, processing legal claims, and executing accounting transactions.

Smart contracts involve money, and they are likely to transact with cryptocurrencies. That makes them ripe targets for attackers. What are the vulnerabilities of smart contracts? What can we do to ensure the safety of a high throughput, automated financial system?

In today’s episode, Haseeb Qureshi talks to Emin Gün Sirer, a professor at Cornell University where he is co-director of the Initiative for Cryptocurrencies and Contracts. They discuss how smart contracts work and how to secure them. Haseeb and Emin are both working full-time on cryptocurrencies, which makes for a detailed technical discussion.

In our previous episode about the DAO hack, Emin Gün Sirer was one of the protagonists of the story. You can find that episode as well as all of our old episodes by downloading the Software Engineering Daily app for iOS and for Android. We also have several other episodes with Haseeb.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Smart Contract Security with Emin Gün Sirer", + "Episodes Uid": "SED6432492015", + "Episodes Audio File": "e07086f1fa13a21e3d34f49ce0418699.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ty", + "Episodes ID": "2f1544ba-e329-11ea-91a2-ebe1b3032cc6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/charles_wood_finale.mp3", + "Episodes Pubdate Date": "2015-10-20", + "Episodes Summary": "

Our conversation covered the world of software podcasting, including a discussion of one of our favorite software podcasts, JavaScript Jabber, a weekly podcast about all things JavaScript, including Node.js, front-end technologies, careers, and teams.

Charles Wood is the host of JavaScript Jabber, Ruby Rogues and several other software podcasts.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

", + "Episodes Title": "JavaScript Jabber with Charles Wood", + "Episodes Uid": "SED4447285862", + "Episodes Audio File": "905f1d42c9d7a9985f61bfa7067f66d9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1z5", + "Episodes ID": "1c7ecf92-e329-11ea-91a2-672efd6f1a1c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/erlang_book_edited.mp3", + "Episodes Pubdate Date": "2016-05-22", + "Episodes Summary": "

Erlang is a programming language with primitives that help software engineers build distributed systems. When a process is malfunctioning in Erlang, the philosophy of the language is to let the process crash–and in a distributed system where unexpected faults happen on a regular basis, this philosophy of “let it crash” simplifies how we reason about an Erlang system.

Other distributed systems advantages of Erlang include the garbage collection strategy. Each process in Erlang has its own garbage collector which means makes it easier to construct systems without a stop-the-world garbage collection.

Francesco Cesarini is the founder of Erlang Solutions, and he joins the show today to discuss the book that he wrote with Steve Vinoski, called Designing for Scalability with Erlang/OTP.

", + "Episodes Title": "Erlang Systems Design with Francesco Cesarini", + "Episodes Uid": "SED3105272074", + "Episodes Audio File": "7743a4a270548941c8c37c0359525f90.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "y6", + "Episodes ID": "2ca6b07e-e329-11ea-91a2-53d3a1341a79", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Jetbrains_Edited.mp3", + "Episodes Pubdate Date": "2015-11-12", + "Episodes Summary": "

Trisha Gee is a Java developer and Java Champion. She is currently a Developer Advocate at JetBrains, where she focuses on educating developers on various tools and IDEs.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Java and Developer Advocacy with Trisha Gee", + "Episodes Uid": "SED3759491771", + "Episodes Audio File": "d42b94753cf161e5b2145fe243bd5828.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1nf", + "Episodes ID": "22c41ace-e329-11ea-91a2-532624018b8b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/eff_edited.mp3", + "Episodes Pubdate Date": "2016-02-20", + "Episodes Summary": "

In this episode, Jeff and Jeremy discuss Internet.org and the criticism it has received from organizations like the EFF. Internet.org is a program created by Facebook whose purpose is to expand the reach of the internet by connecting people in developing nations like India.

However, it has come under fire for its failure to provide “the whole internet” and limiting access to a subset of websites which have to be approved by Facebook. Critics call this a violation of net neutrality and argue that it betrays what the internet stands for – openness and fair access to all destinations. This episodes jumps into the nuances of the debate, with Jeff playing counterpoint to the EFF’s stance – that Internet.org is not the internet.

Jeremy Malcolm is a technologist and lawyer who works for EFF’s international team on issues such as intellectual property, network neutrality, Internet governance, and trade.

", + "Episodes Title": "Internet.org and the Fight for Net Neutrality with Jeremy Malcolm", + "Episodes Uid": "SED7820715124", + "Episodes Audio File": "bc18ba971af73f86c00ec892e54b8e54.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ca", + "Episodes ID": "f50ed29a-e328-11ea-91a2-53233370023e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/sethgodin_ad_free.mp3", + "Episodes Pubdate Date": "2017-12-27", + "Episodes Summary": "

Originally published November 18, 2015

Seth Godin is a writer, speaker, and entrepreneur. He is the author of many books, including most recently, What To Do When It’s Your Turn.

", + "Episodes Title": "Software and Entrepreneurship with Seth Godin Holiday Repeat", + "Episodes Uid": "SED9068163274", + "Episodes Audio File": "2521261f015f1ff9f64e8a18d4d392c1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ey", + "Episodes ID": "0acdc924-e329-11ea-91a2-4f8555fa50df", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/python_dataviz_edited_fixed.mp3", + "Episodes Pubdate Date": "2017-01-16", + "Episodes Summary": "

Data visualization tools are required to translate the findings of data scientists into charts, graphs, and pictures. Understanding how to utilize these tools and display data is necessary for a data scientist to communicate with people in other domains. In this episode, Srini Kadamati hosts a discussion with Jake VanderPlas about the Python ecosystem for data science and the different attempts at creating a data visualization library.

Jake VanderPlas is the Director of Research for Physical Sciences at the University of Washington’s eScience institute, where he also received his PhD in Astronomy. In addition to contributing to many Python data science libraries like scikit-learn, scipy, numpy, and matplotlib, he’s written multiple books that have been published by O’Reilly and has given many talks on data science tools and techniques. He’s also the co-creator of the Altair project, which is a declarative data visualization library for Python built on the Vega-Lite visualization grammar.

", + "Episodes Title": "Python Data Visualization with Jake VanderPlas", + "Episodes Uid": "SED7434786660", + "Episodes Audio File": "7355f439d2ffa0af12dd0b64d7865da7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1y4", + "Episodes ID": "1dadc922-e329-11ea-91a2-43dbd05eabbb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Kelsey_Hightower.mp3", + "Episodes Pubdate Date": "2016-05-02", + "Episodes Summary": "

Kubernetes is an open-source distributed operating system that allows normal engineers to manage their resources at the scale that Google does. With Docker providing the APIs to make containers easy to work with, Kubernetes allows processes to be easily distributed and replicated across a data center.

Kubernetes was created at Google, and today’s guest Kelsey Hightower is a staff developer advocate working at Google. He joins me in a conversation about how Kubernetes works, and why it is important to an average developer. We touch on how software engineering is going to look in the next 5-10 years, and how a lot of the work around distributed systems will become much easier over time.

", + "Episodes Title": "Kubernetes, Docker, and the Distributed Operating System with Kelsey Hightower", + "Episodes Uid": "SED2352297233", + "Episodes Audio File": "8810ce80f07edc5378393fed2abd5e30.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1z0", + "Episodes ID": "1cb384ee-e329-11ea-91a2-f752c6e22202", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Magic_Pocket.mp3", + "Episodes Pubdate Date": "2016-05-18", + "Episodes Summary": "

Dropbox has been storing files on Amazon Web Services for 8 years, and Dropbox’s core business is storing files. For the past three years, Dropbox has been working on a project to migrate its file storage from Amazon Web Services to its own custom built infrastructure. Magic Pocket is the name of Dropbox’s new infrastructure layer, and it gives Dropbox more control and improved economics.

James Cowling leads the storage team at Dropbox. On today’s episode, James takes us into the architecture of Dropbox and explains how the team moved all of the user file storage from Amazon S3 to Dropbox’s Magic Pocket infrastructure. Dropbox’s architecture is built with a focus on simplicity–and there are numerous challenges to maintaining that simplicity in the face of an extremely complex problem like this.

", + "Episodes Title": "Dropbox’s Magic Pocket with James Cowling", + "Episodes Uid": "SED1566994372", + "Episodes Audio File": "d958ef83df81b44488f129e2d4f59d4b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ya", + "Episodes ID": "1d720c84-e329-11ea-91a2-9ba20c8395ed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Adam_and_Jerod.mp3", + "Episodes Pubdate Date": "2016-05-06", + "Episodes Summary": "

The Changelog is one of the most popular Software Engineering Podcasts in existence.

Open source software moves fast, and The Changelog helps developers keep up with that rapid pace by publishing consistent podcasts and newsletters. When I started Software Engineering Daily, Changelog was one of the shows that I looked at for inspiration on how to succeed as a software podcaster.

Adam Stacoviak and Jerod Santo are the hosts of The Changelog, and they join me today to talk about how open source has changed since they started the podcast in 2009, and how it will change in the near future.

", + "Episodes Title": "The Changelog with Adam Stacoviak and Jerod Santo", + "Episodes Uid": "SED7569235201", + "Episodes Audio File": "9afff82665f1526d3a2a1f296e419180.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 306, + "Episodes ID": "f6c2dd66-e328-11ea-91a2-23a91adcdf3f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ShailinPresentation.mp3", + "Episodes Pubdate Date": "2017-08-23", + "Episodes Summary": "

The Internet runs on advertising. Advertising is subject to fraud–but then again, so is every system of online transactions. The amount of money lost in electronic payments fraud and ecommerce scamming is probably much greater than what is lost due to ad fraud. So why do we keep covering advertising fraud on Software Engineering Daily?

More of our audience needs to know about ad fraud. Few people realize how much fraud there is in online advertising. In previous episodes of Software Engineering Daily, we have explained, how advertising fraud works, why it is absurd and disgraceful, and why nobody talks about.

We also cover ad fraud because I personally find it interesting and sometimes hilarious. Those are the same reasons I invited Shailin Dhar to speak at the third Software Engineering Daily Meetup. Shailin has been on the show twice before and he will be on again in the future. He has made it a full time job to expose ad fraud, and he gives a great presentation on the topic in this episode.

", + "Episodes Title": "Ad Fraud Overview with Shailin Dhar", + "Episodes Uid": "SED9404539629", + "Episodes Audio File": "28a9931b43ff9565f1cd0902a675a5be.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5d", + "Episodes ID": "37cb815a-e329-11ea-91a2-ab2d80cc4040", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/matei_spark.mp3", + "Episodes Pubdate Date": "2015-08-03", + "Episodes Summary": "

Matei Zaharia created Spark, and is the co-founder of Databricks, a company using Spark to power data science.

", + "Episodes Title": "Apache Spark Creator Matei Zaharia Interview", + "Episodes Uid": "SED2369111546", + "Episodes Audio File": "0b8559f6429e58eb0b12b063d21a164c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 41, + "Episodes ID": "3811eda2-e329-11ea-91a2-c7cedb072061", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/javascript_mattias.mp3", + "Episodes Pubdate Date": "2015-08-01", + "Episodes Summary": "

Questions include:

Links:

", + "Episodes Title": "JavaScript at Spotify with Mattias Petter Johansson", + "Episodes Uid": "SED4474714745", + "Episodes Audio File": "94c61a485c604daf24f1071615360ba1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "nk", + "Episodes ID": "31d0781e-e329-11ea-91a2-5be94792894f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/sukrutha_bhadouria.mp3", + "Episodes Pubdate Date": "2015-09-24", + "Episodes Summary": "

Well-known tech companies of Silicon Valley sponsor the next generation of female software engineers emerging from these dinners.

Sukrutha Bhadouria is a software engineer at Salesforce and the Managing Director of Bay Area Girl Geek Dinners.

", + "Episodes Title": "Girl Geek Dinners with Sukrutha Bhadouria", + "Episodes Uid": "SED3153848551", + "Episodes Audio File": "f50da4c4ab70d26ef7aaec27d304c600.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 69, + "Episodes ID": "37aa1e5c-e329-11ea-91a2-1b9823e4f7b6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/venkatesth_hortonworks.mp3", + "Episodes Pubdate Date": "2015-08-08", + "Episodes Summary": "

Venkatesh Seetharam is a software engineer at Hortonworks. He has worked on several Apache projects, including Hadoop, Falcon, and Atlas.

", + "Episodes Title": "Hortonworks Data Platform with Venkatesh Seetharam", + "Episodes Uid": "SED5768305554", + "Episodes Audio File": "0a5c21b8ff237c03989f1883d40dff6f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2c", + "Episodes ID": "38d4afc2-e329-11ea-91a2-b3c5d19f737b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/meteor_uri.mp3", + "Episodes Pubdate Date": "2015-07-28", + "Episodes Summary": "

Meteor is a full-stack web framework for building isomorphic JavaScript applications.

Questions include:

Links:

", + "Episodes Title": "Meteor.js with Uri Goldshtein", + "Episodes Uid": "SED8917545726", + "Episodes Audio File": "222a9dd463fa338267bdf311212b8e6d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "b3", + "Episodes ID": "36cbf85c-e329-11ea-91a2-87d31c98d0b8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/rethinkdb_slava.mp3", + "Episodes Pubdate Date": "2015-08-19", + "Episodes Summary": "

RethinkDB pushes changes to the application rather than waiting for a request.

Slava Akhmechet is the CEO of RethinkDB.

", + "Episodes Title": "Push Databases with RethinkDB CEO Slava Akhmechet", + "Episodes Uid": "SED8841770176", + "Episodes Audio File": "64e0fd61348fdcf6a513f04c12307a40.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 19, + "Episodes ID": "38e94f72-e329-11ea-91a2-d369e8889b2e", + "Episodes Original URL": "http://softwaredaily.wpengine.com/wp-content/uploads/2015/07/yad_js.mp3", + "Episodes Pubdate Date": "2015-07-15", + "Episodes Summary": "

In Episode 0 of SE Daily, Yad and Jeff give a prologue to many of the topics that will be covered in JavaScript Week.

Right-click to download the episode.

Links:

", + "Episodes Title": "JavaScript Overview with Yad Faeq", + "Episodes Uid": "SED5531251911", + "Episodes Audio File": "79319e6b54e3c21e97a89162be9ba853.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3i", + "Episodes ID": "37c04a1a-e329-11ea-91a2-5f51b6345437", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/guozhang_kafka.mp3", + "Episodes Pubdate Date": "2015-08-06", + "Episodes Summary": "

Guozhang Wang is an engineer at Confluent, which offers a stream data platform built using Kafka.

", + "Episodes Title": "Apache Kafka with Guozhang Wang", + "Episodes Uid": "SED1730528721", + "Episodes Audio File": "ec29953bcf8aec1407c105599cb65899.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "9o", + "Episodes ID": "36e98c28-e329-11ea-91a2-1f3c3d656d75", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/bitcoin_andreas.mp3", + "Episodes Pubdate Date": "2015-08-14", + "Episodes Summary": "

Andreas Antonopoulos is a bitcoin researcher, journalist, and evangelist.

", + "Episodes Title": "Bitcoin with Andreas Antonopoulos", + "Episodes Uid": "SED7460027969", + "Episodes Audio File": "cc6d089904c7cb8f7ff0864cc1b324d0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7h", + "Episodes ID": "3766b07c-e329-11ea-91a2-e36989d29107", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/mmiller_btc_intro.mp3", + "Episodes Pubdate Date": "2015-08-10", + "Episodes Summary": "

Michael Miller is the author of “The Ultimate Guide To Bitcoin” and 150 other books. Michael is an expert in explaining complex topics in ways which are comprehensible to the layperson.

", + "Episodes Title": "Bitcoin Introduction with Michael Miller", + "Episodes Uid": "SED3896703796", + "Episodes Audio File": "f24daba60783b49c69025e045bbd45ad.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ab", + "Episodes ID": "36d8000c-e329-11ea-91a2-5f58e415a199", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/sidechains_rusty_russell_fixed.mp3", + "Episodes Pubdate Date": "2015-08-17", + "Episodes Summary": "

Rusty Russell is an Australian free software programmer and advocate, known for his work on the Linux kernel’s networking subsytem and the Filesystem Hierarchy Standard.

", + "Episodes Title": "Sidechains and Lightning Networks with Rusty Russell", + "Episodes Uid": "SED2307312626", + "Episodes Audio File": "cf0d427f9302c84a15028a069e12ab1c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "g9", + "Episodes ID": "346f89d4-e329-11ea-91a2-47cbdc82ad2c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/max_krohn_keybase.mp3", + "Episodes Pubdate Date": "2015-09-04", + "Episodes Summary": "

Max Krohn is the co-founder of Keybase, and previously co-founded OKCupid and SparkNotes.

", + "Episodes Title": "Identity and Encryption with Keybase Founder Max Krohn", + "Episodes Uid": "SED6709391004", + "Episodes Audio File": "532abcdb0ab9e2a516a0f38b755875a1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "36n", + "Episodes ID": "f5d0997a-e328-11ea-91a2-ef41529c0588", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ScopeAR.mp3", + "Episodes Pubdate Date": "2017-11-01", + "Episodes Summary": "

Augmented reality applications are slowly making their way into the world of the consumer. Pokemon Go created the magical experience of seeing Pokemon superimposed upon the real world. IKEA’s mobile app lets you see how a couch would fit into your living room, which has a significant improvement on the furniture buying process.

Augmented reality applications can have even more dramatic impact on industrial enterprises.

Have you ever set up a factory? You might need to build a conveyor belt. You might need to put together the parts of a giant machine that extrudes steel. You might need to fix a silicon wafer fabrication machine. It takes an expert to set up these heavy, complicated machines.

ScopeAR is a company that builds augmented reality tools. One of the ScopeAR products allows users to telepresence with each other to collaborate on the construction and maintenance of heavy machinery.

Imagine I am setting up my factory, and I have a complicated piece of machinery (let’s say a conveyor belt) in front of me. I have never constructed a conveyor belt before. I put on a HoloLens, and set up a VoIP call with an expert who has experience with that piece of machinery, and they point out what I need to do by superimposing 3-D arrows, text, and other instructions on my field of vision. They can share my experience and help guide me through the process.

This is such a flexible tool–you can imagine applications for augmented reality assistance being useful in medicine, construction, education and other fields.

Scott Montgomerie is the CEO of ScopeAR and in today’s episode, we talk about the state of AR, how the AR tools from Apple and Google compare, and how the similarity between tools used for mapping the world in AR relate to the tools used to map the world by autonomous cars.

Scott was a great guest, and I hope to have him back on in the future.

We have done some great shows about how to build augmented reality and virtual reality applications. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Shout out to today’s featured contributor Edgar Pino. He is working on a real-time chat application for Software Engineering Daily, so that we can have chat rooms for people to discuss the episodes easily. Innovative work!

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Augmented Reality with Scott Montgomerie", + "Episodes Uid": "SED9201782255", + "Episodes Audio File": "2aadc810cb0481a0e710973e56a93ceb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3lm", + "Episodes ID": "f3d402b0-e328-11ea-91a2-07f052a2e1da", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_22_Streamr.mp3", + "Episodes Pubdate Date": "2018-03-22", + "Episodes Summary": "

Data streams about the weather can be used to predict how soybean futures are going to change in price. Satellite data streams can take pictures of the number of cars on the road, and judge how traffic patterns are changing. Search engines can aggregate data from different queries and determine what people are most interested in.

Data streams define how the world is changing over time. Technology companies process these data streams and make decisions based on that stream. The most direct example of this might be financial trading companies, which use all kinds of data streams to predict economic price changes.

When Henri Pihkala worked on algorithmic trading systems, he saw how useful these data streams are, and decided to build products around data streaming. Eventually, Henri started working on Streamr, a platform for data streams to be bought and sold on top of the Ethereum network.

Streamr is an adaptation of technology that Henri worked on before he started working on the decentralized version. The original technology is a user interface for connecting data streams and building applications on top of them, and he acquired several customers for that platform. Today, the Streamr platform is still mostly centralized, but Henri and his team are working on building out the decentralized infrastructure.

Streamr raised an ICO worth ~25 million Euros. Most startups would not raise this amount of money before series B, much less before they have a product with a large user base. In this episode, Henri discusses why they raised so much money, and explains why ICOs are different than equity raises. The investors who participated in the Streamr ICO received the DATAcoin token. Henri also explained why it makes sense for this ecosystem to have its own token.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Streamr: Data Streaming Marketplace with Henri Pihkala", + "Episodes Uid": "SED1342763268", + "Episodes Audio File": "13f1b67206e4a585100846464086378f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5v6", + "Episodes ID": "ed8fd000-e328-11ea-91a2-57dcd06d454e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_24_Clubhouse.io.mp3", + "Episodes Pubdate Date": "2019-06-24", + "Episodes Summary": "

Software projects are organized and planned using project management software. Examples of project management software include JIRA, Trello, and Asana. There are hundreds of tools for managing a software project because there are infinite ways that a project could be managed.

Google Docs changed project management by allowing documents to be easier to share and collaborate on. Newer SaaS tools such as Slack, Dropbox, and Notion have taken the design lessons from social networking apps to make enterprise software more engaging.

As the tools improve, our project management strategies change, and new software tools emerge to fit those new management strategies.

Kurt Schrader is the CEO of Clubhouse, a project management tool for software engineers. Kurt joins the show to talk about the history and future of project management tools. He also discusses the engineering challenges of improving performance on a complicated webapp. Project management tools often have to load hundreds of small objects on a page, which required performance optimizations in the Clubhouse frontend JavaScript library.

", + "Episodes Title": "Project Management with Kurt Schrader", + "Episodes Uid": "SED5179333921", + "Episodes Audio File": "d32603826a5b9c157c637253c67fb264.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2j5", + "Episodes ID": "0489d058-e329-11ea-91a2-7f861ffa4134", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/stripe_observability_edited.mp3", + "Episodes Pubdate Date": "2017-03-15", + "Episodes Summary": "

Observability allows engineers to understand what is going on inside their systems. In its most raw form, observability comes from log data. Modern systems have many layers of logs–virtualized cloud infrastructure, container orchestration, the container runtime itself, and the application logic running within the container.

With all of these layers, it is not practical for a developer to have to sift through layers of logs every time a bug occurs in production, or a deployment fails integration tests. Higher level observability tools include charts, distributed tracing tools, and monitoring services. With proper observability, developers can save time during incident response. Day-to-day software development becomes safer and more comfortable.

Stripe is a payments company for developers. This episode is the first in a series of episodes profiling different aspects of the company. Our guest Cory Watson leads the observability team at Stripe. In subsequent episodes, we will explore infrastructure and machine learning at Stripe.

Throughout these episodes, you will get a sense for how Stripe’s engineering culture works. We hope to do more experimental series like this in the future. Please give us feedback for what you think of the format by sending us email, joining the Slack group, or filling out our listener survey. All of these things are available on softwareengineeringdaily.com.

", + "Episodes Title": "Stripe Observability with Cory Watson", + "Episodes Uid": "SED9063327539", + "Episodes Audio File": "c4a24b3ed31701c8701da83771b54136.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3mb", + "Episodes ID": "f3ba4d48-e328-11ea-91a2-174163b8f217", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_29_EnterpriseBlockchains.mp3", + "Episodes Pubdate Date": "2018-03-29", + "Episodes Summary": "

We sign many different types of contracts throughout our lives. We sign a mortgage to get a loan for a house. When we go to the hospital, we sign a piece of paper that defines how our medical data can be shared between organizations. These pieces of paper represent our opting into an agreement that will be mediated and enforced by computer interactions. We can’t see the code behind those computer interactions, and we can’t verify that it is abiding by the contract we agreed to.

Smart contracts allow for programmatic execution of contractual agreements. Code is law, and there is less ambiguity. The most widely used smart contract platform is the Ethereum blockchain–but several large enterprises are creating their own smart contracts. Should all smart contracts be decentralized, or do enterprise consortium blockchains make sense?

In this episode, Marley Gray from Microsoft joins the show to discuss enterprise smart contracts–why you would want to use them and how they can be architected. Marley has worked on banking and financial technology for over a decade, and makes some strong arguments for why banks will adopt smart contracts, and the timeline for how that might take place.

We would love for you to fill out our listener survey at softwareengineeringdaily.com/survey. This will help us decide what other content to focus on.

Of course–you can also send me an email at any time, jeff@softwaredaily.com. And in the meantime, if you are completely sick of cryptocurrencies, check out our back catalog of episodes at softwaredaily.com, or by downloading our apps, which have all of our episodes including our Greatest Hits, which is a curated set of the most popular shows. The apps will soon have offline downloads and bookmarking.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Enterprise Smart Contracts with Marley Gray", + "Episodes Uid": "SED6573308411", + "Episodes Audio File": "10c6f1d9311f82ee8aae6e2283cf12d4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2g1", + "Episodes ID": "08f685e6-e329-11ea-91a2-6bc876647c73", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/realitywithdonaldhoffman_edited.mp3", + "Episodes Pubdate Date": "2017-02-02", + "Episodes Summary": "

What is the relationship between your brain and your conscious experiences? This is is the fundamental question of the work of Donald Hoffman, a professor of computer science and cognitive science at UC Irvine.

When Hoffman was a child, he wondered whether there was a cognitive dividing line between humans and machines, and that curiosity has driven him to his current work–building a mathematical framework which we can use to model consciousness.

Humans would like to believe that evolution selects for traits that allow us to understand the world as it is. From his experimental simulations, Hoffman has shown the opposite–that evolution pushes us towards a mistaken version of reality.

For listeners who are interested in theories about whether we live in a simulation, this episode is for you. If you are skeptical of the simulation theory then this episode will also be useful for you, as Hoffman gives one of the most nuanced, comprehensive explanations of reality that I have heard.

TED Talk

The Case Against Reality

", + "Episodes Title": "Reality with Donald Hoffman", + "Episodes Uid": "SED9301596845", + "Episodes Audio File": "0d7953e8f4d09f504b65afa321e8ca6e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ge", + "Episodes ID": "f47d93de-e328-11ea-91a2-6b214a81a826", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_02_Gremlin.mp3", + "Episodes Pubdate Date": "2018-02-02", + "Episodes Summary": "

The number of ways that applications can fail are numerous. Disks fail all the time. Servers overheat. Network connections get flaky. You assume that you are prepared for such a scenario, because you have replicated your servers. You have the database backed up. Your core application is spread across multiple availability zones.

But are you really sure that your system is resilient? The only way to prove that your system is resilient to failure is to experience failure, and to make swift responsiveness to failure an integral part of your software.

Chaos engineering is the practice of routinely testing your system’s resilience by inducing controlled failures. Netflix was the first company to discuss chaos engineering widely, but more and more companies are starting to work it into their systems, and finding it tremendously useful. By inducing failures in your system, you can discover unknown dependencies, single points of failure, and problematic state conditions that can cause data corruption.

Kolton Andrus worked on chaos engineering at Netflix and Amazon, where he designed systems that would test system resiliency through routine failures. Since then, he founded Gremlin, a company that provides chaos engineering as a service. In a previous episode, Kolton and I discussed why chaos engineering is useful, and he told some awesome war stories about working at Amazon and Netflix. In this show, we explore how to build a chaos engineering service–which involves standing up Gremlin containers that institute controlled failures.

To find the previous episode I recorded with Kolton, as well as other supplementary materials described in this show, download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Chaos Engineering with Kolton Andrus", + "Episodes Uid": "SED3280599196", + "Episodes Audio File": "314734557297a45f00f09df84f135bba.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "37c", + "Episodes ID": "f5b74146-e328-11ea-91a2-3bce7403228c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/OpenBazaar.mp3", + "Episodes Pubdate Date": "2017-11-08", + "Episodes Summary": "

Cryptocurrencies give us a decentralized financial system. OpenBazaar is a decentralized commerce system.

A merchant can log onto OpenBazaar and post a listing for an item–for example, a t-shirt that I want to sell for $15. My item listing will spread throughout the OpenBazaar P2P network. A shopper can download the OpenBazaar desktop application and see my listing for a t-shirt. The shopper can pay me $15 in bitcoin, and I will send the t-shirt to their address.

If I were selling that shirt on Amazon, the corporation would take a cut of that transaction. OpenBazaar has no transaction costs–so users get to save some money. However, users also miss out on the benefits of a corporate marketplace.

Amazon makes sure that the seller will send the item to the buyer, and makes sure that the buyer pays the seller. On OpenBazaar, an escrow system is needed to place money in the hands of a neutral third party until the goods are delivered. Amazon ensures that the distributor sends the item to the customer. On OpenBazaar, users need to figure out how to send the goods to each other.

Brian Hoffman was the first developer to start working on OpenBazaar. The project has grown significantly since his initial commit, and OpenBazaar now has buyers, sellers, and open source committers. There is a clear desire for an open system of commerce.  Brian is also the CEO of OB1, a company that provides services on top of OpenBazaar. OpenBazaar is a protocol–and other companies will undoubtedly emerge to build on top of it as well.

In our conversation, Brian discussed how OpenBazaar works–the peer-to-peer protocol, the escrow system, the dispute resolution, and the open source community management. It is a fascinating, unique project, and I hope you learn something about it from this episode.

To find all of our old episodes about decentralized technology and blockchains, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Shout out to today’s featured open source contributor Justin Lam. He has been working on improving the iOS codebase, and I know all the SE Daily mobile users appreciate his effort. Thanks Justin!

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "OpenBazaar with Brian Hoffman", + "Episodes Uid": "SED4191317948", + "Episodes Audio File": "a0db4ded7c266f9d8a15c47d13ae92cb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "44n", + "Episodes ID": "f26bcdfe-e328-11ea-91a2-e33e4d60ff44", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_29_Outlier.mp3", + "Episodes Pubdate Date": "2018-06-29", + "Episodes Summary": "

Every company has the idea of the “nightly report.” A business analyst comes into the office, sits down in front their inbox, and looks at yesterday’s data. Did sales go up? Did the marketing campaigns bring in the expected number of customers? Was there an increase in helpdesk tickets? The statistics that these reports deliver to human analysts can change the direction of the business.

Everyone within a company could use a regular report that documents how the business is changing over time. Outlier.ai is a company that processes the data sets within a business and generates automated reports that are relevant to different people within the organization.

If you are an email marketing analyst, your data from MailChimp campaigns will be analyzed. If you manage a customer success team, your Zendesk tickets will be analyzed. If you are a technical support analyst, the crash reports and error messages from your users will be analyzed. In all of these cases, the data gets processed automatically, and a story is sent to you, so that you can have the information in your inbox waiting for you, instead of having to go ask a data scientist to generate it for you.

Mike Kim is the CTO of Outlier.ai, and in this show he describes the engineering challenges of integrating with all the different data sets of an organization–and why there is so much value in the idea of the automated “report” or “story” for analysts.

In past shows, we have explored how data engineering has progressed over the last twenty years–from database administration to Hadoop cluster management to the emergence of “data breadlines” where analysts wait for a data scientist to process the job they asked for. Outlier represents a step towards a world where the data science reports are delivered to us before we even ask, rather than us having to query the system.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Data Engineering Automation with Mike Kim", + "Episodes Uid": "SED4480280010", + "Episodes Audio File": "5a6583a202a7dc3d0acfd7b5a2e04e75.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2mu", + "Episodes ID": "fd3e873a-e328-11ea-91a2-179a11b180ba", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ZencastrEngineering.mp3", + "Episodes Pubdate Date": "2017-05-03", + "Episodes Summary": "

There are certain experiences when a product solves a problem so thoroughly and elegantly that it lifts a weight off of your shoulders that you didn’t even know was there. Dropbox did this with file storage. Slack did this with group collaboration. Zencastr does this for recording podcasts.

Before I used Zencastr to record my podcasts, like most podcasters, I used a Skype plugin. There were a number of inconveniences in the podcaster workflow from Skype. Zencastr solved all of these by creating a podcast recording tool in the browser and presenting a simple user interface.

Josh Nielsen joins the show to talk about the challenges of building a podcasting tool in the browser, and the new technologies that make it easier, such as WebRTC.

We would love to get your feedback on Software Engineering Daily. Please fill out the listener survey, available on softwareengineeringdaily.com/survey. Also–Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to download the transcript for this episode.

", + "Episodes Title": "Zencastr with Josh Nielsen", + "Episodes Uid": "SED6374860693", + "Episodes Audio File": "57204241c1bd33c510582d9e79135e4b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2im", + "Episodes ID": "0539dc14-e329-11ea-91a2-af5a21ce672e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/loadtesting_edited.mp3", + "Episodes Pubdate Date": "2017-03-08", + "Episodes Summary": "

Load testing measures performance of a system undergoing a large volume of requests. Before an application is pushed to production, engineers will often load test their software to ensure it is resilient in the face of high traffic.

As web applications have changed, the requirements around load testing have changed as well. External APIs, internal undocumented APIs, and proprietary databases are black boxes that you might not be able to test reliably with unit tests or integration tests. Having an end-to-end load testing system can provide a measure of insurance against unknown unknowns before users start engaging with a production version.

Mark Gilbert works on performance engineering at Apica, and he joins the show to discuss how load testing software is built and when engineers should use it. Full disclosure: Apica is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Load Testing with Mark Gilbert", + "Episodes Uid": "SED5246248658", + "Episodes Audio File": "367735025a2237173d29400f0245e2a0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "35v", + "Episodes ID": "f5ed7a9a-e328-11ea-91a2-abef1a1ed6ba", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Dremio.mp3", + "Episodes Pubdate Date": "2017-10-25", + "Episodes Summary": "

The MapReduce paper was published by Google in 2004. MapReduce is an algorithm that describes how to do large-scale data processing on large clusters of commodity hardware.

The MapReduce paper marked the beginning of the “big data” movement. The Hadoop project is an open source implementation of the MapReduce paper. Doug Cutting and Mike Cafarella wrote software that allowed anybody to use MapReduce, as long as they had significant server operations knowledge and a rack of commodity servers.

Hadoop got deployed first at companies with the internal engineering teams that could recognize its importance and implement it–companies like Yahoo and Microsoft. The word quickly spread about the leverage Hadoop could provide.

Around this time, every large company was waking up to the fact that they had tons of data and didn’t know how to take advantage of it. Billion dollar corporations in areas like banking, insurance, manufacturing, and agriculture all wanted to take advantage of this amazing new way of looking at their data. But these companies did not have the engineering expertise to deploy Hadoop clusters.

Three big companies were formed to help bring Hadoop to large enterprises: Cloudera, Hortonworks, and MapR. Each of these companies worked with hundreds of large enterprise clients to build out their Hadoop clusters and help them access their data. Tomer Shiran spent five years at MapR, seeing the data problems of these large enterprises and observing how much value could be created by solving these data problems.

In 2015, eleven years had passed since MapReduce was first published, and companies were still having data problems. Tomer started working on Dremio, a company that was in stealth for another two years. I interviewed Tomer two years ago, when he still could not say much about what Dremio was doing. We talked about Apache Drill, an open-source project related to what Dremio eventually built.

Earlier this year, two of Tomer’s colleagues Jacques Nadeau and Julien Le Dem came on to discuss columnar data storage and interoperability. What I took away from that conversation was that today, data within an average enterprise is accessible, but the different formats are a problem. Some data is in MySQL, some is in Amazon S3, some is in ElasticSearch, some is on HDFS stored in Parquet files. Different teams will set up different BI tools and charts that read from a specific silo of data.

At the lowest level, the different data formats are incompatible–you have to transform MySQL data in order to merge it with S3 data. On top of that, engineers doing data science work are using Spark, Pandas, and other tools that pull lots of data into memory–if the in-memory formats are not compatible, the data teams can’t get the most out of their work. On top of THAT, at the highest level, data analysts are working with different data analysis tools, so there is even more siloing.

Now I understand why Dremio took two years to bring to market.

They are trying to solve data interoperability by making it easy to transform data sets between different formats. They are trying to solve data access speed by creating a sophisticated caching system. And they are trying to improve the effectiveness of the data analysts by providing the right abstractions for someone who is not a software engineer to study the different data sets across an organization.

Dremio is an exciting project because it is rare to see a pure software company put so many years into up-front stealth product development. After talking to Tomer in this conversation, I’m looking forward to seeing Dremio come to market. It was fascinating to hear him talk about how data engineering has evolved to today.

Some of the best episodes of Software Engineering Daily cover the history of data engineering, including an interview with Mike Cafarella, the co-founder of Hadoop, and another episode called “The History of Hadoop” in which we explored how Hadoop made it from a Google research paper into a multibillion dollar industry.

To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

", + "Episodes Title": "Dremio with Tomer Shiran", + "Episodes Uid": "SED6010461199", + "Episodes Audio File": "c7b9e00b8c408c8353dc6348e88a6c3b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2s7", + "Episodes ID": "f9f54744-e328-11ea-91a2-ebfdd1750460", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RoundtableABKP.mp3", + "Episodes Pubdate Date": "2017-06-07", + "Episodes Summary": "

Engineers have plenty to be skeptical about. We look to data sets to give us something resembling objective truth. Some areas of research have so many variables that it is hard to isolate facts. Kyle Polich hosts the popular data science show Data Skeptic, where he examines problems and solutions around data, and he is one of the guests today in our round table discussion.

There are some big unanswered questions in our world that might eventually be solved with enough data and the right scientific approach: nutrition, or drug discovery, or image classification. The hiring process is like this. How can you predict whether an engineer will make for a good hire? Ammon Bartram of Triplebyte is working on solving the hiring process for engineering organizations and he is the other guest for this roundtable episode.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Skepticism Roundtable with Ammon Bartram and Kyle Polich", + "Episodes Uid": "SED7864942170", + "Episodes Audio File": "e3df92728bf2b237428c0a00dc37144a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3d5", + "Episodes ID": "f4e2d5c8-e328-11ea-91a2-ab7fb3f7ef3c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DistributedTracing.mp3", + "Episodes Pubdate Date": "2018-01-11", + "Episodes Summary": "

You are requesting a car from a ridesharing service such as Lyft.

Your request hits the Lyft servers and begins trying to get you a car. It takes your geolocation, and passes the geolocation to a service that finds cars that are nearby, and puts all those cars into a list. The list of nearby cars is sent to another service, which sorts the list of cars by how close they are to you, and how high their star rating is. Finally, your car is selected, and sent back to your phone in a response from the server.

In a “microservices” environment, multiple services often work together to accomplish a user task. In the example I just gave, one service took a geolocation and turned it into a list, another service took a list and sorted it, and another service sent the actual response back to the user.

This is a common pattern: Service A calls service B, which calls service C, and so on.  When one of those services fails along the way, how do you identify which one it was? When one of those services fails to deliver a response quickly, how do you know where your latency is coming from?

The solution is distributed tracing. To implement distributed tracing, each user level request gets a request identifier associated with it. When service A calls service B, it also hands off the unique request ID, so that the overall request can be traced as it passes through the distributed system (and if that doesn’t make sense–don’t worry, we explain it again during the show).

Ben Sigelman began working on distributed tracing when he was at Google and authored the “Dapper” paper. Dapper was implemented at Google to help debug some of the distributed systems problems faced by the engineers who work on Google infrastructure.

A request that moves through several different services spends time processing on each of those services. A distributed tracing system measures the time spent in each of those services–that time spent is called a span. A single request that has to hit 20 different services will have 20 spans associated with it. Those spans get collected into a trace. A trace can be evaluated to look at the latencies of each of those services.

If you are trying to improve the speed of a distributed systems infrastructure, distributed tracing can be very helpful for choosing where to focus your attention.

The published Google papers of ten years ago often turn out to be the companies of today. Some examples include MapReduce (which formed the basis of Cloudera), Spanner (which formed the basis of CockroachDB), and Dremel (which formed the basis of Dremio).

Today, a decade after he started thinking about distributed tracing, Ben Sigelman is the CEO of Lightstep, a company that provides distributed tracing and other monitoring technologies.

Lightstep’s distributed tracing model still bears a resemblance to the same techniques described in the paper–so I was eager to learn the differences between open source versions of distributed tracing (such as OpenZipkin) and enterprise providers such as Lightstep.

The key feature of Lightstep that we discussed: garbage collection.

If you are using a distributed tracing system, you could be collecting a lot of traces. You could collect a trace for every single user request. Not all of these traces are useful–but some of them are very useful. Maybe you only want to keep track of traces that take an exceptionally long latency. Maybe you want to keep every trace in the last 5 days, and destroy them over time. So, the question of how to manage the storage footprint of those traces was as interesting as the discussion of distributed tracing itself.

Beyond the distributed tracing features of his product, Ben has a vision for how his company can provide other observability tools over time. I spoke to Ben at Kubecon–and although this conversation does not talk about Kubernetes specifically, this topic is undoubtedly interesting to people who are building Kubernetes technologies.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "High Volume Distributed Tracing with Ben Sigelman", + "Episodes Uid": "SED1210480662", + "Episodes Audio File": "19b39157b103bf8207ea4a1f2e802c34.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3nb", + "Episodes ID": "f39d7092-e328-11ea-91a2-978fd83839e2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_06_IPFSDavidDias.mp3", + "Episodes Pubdate Date": "2018-04-06", + "Episodes Summary": "

The Interplanetary File System (IPFS) is a decentralized global, peer-to-peer file system. IPFS combines ideas from BitTorrent, Git, and Bitcoin, creating a new way to store and access objects across the Internet.

When you access an object on almost any website, you are accessing the object via a location address—a URL. The URL tells you where to find the object. If the object is a photo on Facebook that you are linking to, the URL will have an address of somewhere on Facebook. Other objects that we access through URLs include web pages, videos, and JavaScript import packages.

URLs seem natural to us. You look up an object based on where that object is being stored. Why would you do anything differently?

A downside of location addressing is that if the location disappears, you can no longer access that object. If a government decides to censor a website that I wanted to visit, the government can shut down access to the server where that website sits, and my link will break. This happened in Turkey—where Wikipedia was shut down last year.

Objects in IPFS are content addressed—you access an object by giving IPFS a cryptographic hash of the object, and IPFS will find someone on the network who has a copy of that object, and give you access to it.

To look up a webpage in an IPFS browser, you put the content address in the address bar. When the HTML for that page is received, that page might have lots of other content-addressed files referred to on the page. Your browser can also grab all of those content-addressed files from the IPFS P2P network.

In this episode, David Dias explains how IPFS is designed. David is an engineer at Protocol Labs, the company building out IPFS. This episode is a great companion to our previous show with Juan Benet, the creator of IPFS.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "IPFS Design with David Dias", + "Episodes Uid": "SED6892231537", + "Episodes Audio File": "2d08e181ee623300d622baaae40bc87c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ye", + "Episodes ID": "f6f756fe-e328-11ea-91a2-0f6ce87a26ce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/IoTJeremyFoster.mp3", + "Episodes Pubdate Date": "2017-08-08", + "Episodes Summary": "

The Internet of Things is the concept that traditionally analog objects, like thermostats and lightbulbs, can be given digital guts and connected to the internet to create more value for users. From Nest thermostats to Phillips Hue lightbulbs, these connected things are starting to enter the mainstream. According to recent estimates by Gartner, over eight billion connected “Things” will be in use in 2017, with that number ballooning to over twenty billion by 2020.

Jeremy Foster is a Technical Evangelist at Microsoft and the host of Microsoft Virtual Academy’s “Introduction to Azure IoT” course. In this episode, host Jared Porcenaluk joins Jeremy to discuss developing for the Internet of Things.

", + "Episodes Title": "IoT Overview with Jeremy Foster", + "Episodes Uid": "SED4630913072", + "Episodes Audio File": "6c502fd3150786e16247503c380ef80d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2sg", + "Episodes ID": "f97b52cc-e328-11ea-91a2-8b11962e5aeb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Distributeddeeplearning.mp3", + "Episodes Pubdate Date": "2017-06-14", + "Episodes Summary": "

Deep learning allows engineers to build models that can make decisions based on training data. These models improve over time using stochastic gradient descent. When a model gets big enough, the training must be broken up across multiple machines. Two strategies for doing this are “model parallelism” which divides the model across machines and “data parallelism” which divides the data across multiple copies of the model.

Distributed deep learning brings together two advanced software engineering concepts: distributed systems and deep learning. In this episode, Will Constable, the head of distributed deep learning algorithms at Intel Nervana, joins the show to give us a refresher on deep learning and explain how to parallelize training a model.

Full disclosure: Intel is a sponsor of Software Engineering Daily, and if you want to find out more about Intel Nervana including other interviews and job postings, go to softwareengineeringdaily.com/intel. Intel Nervana is looking for great engineers at all levels of the stack, and in this episode we’ll dive into some of the problems the Intel Nervana team is solving.

Related episodes about machine learning can be found here.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Distributed Deep Learning with Will Constable", + "Episodes Uid": "SED3935396109", + "Episodes Audio File": "f89b550233b29a0887ac38b8f7feaded.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "38g", + "Episodes ID": "f58ddffe-e328-11ea-91a2-afbf6772e7c4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/IntercomEngineering.mp3", + "Episodes Pubdate Date": "2017-11-20", + "Episodes Summary": "

There is a quote from Jeff Bezos: “70% of the work of building a business today is undifferentiated heavy lifting. Only 30% is creative work. Things will be more exciting when those numbers are inverted.”

That quote is from 2006, before Amazon Web Services had built most of their managed services. In 2006, you had no choice but to manage your own database, data warehouse, and search cluster. If your server crashed in the middle of the night, you had to wake up and fix it. And you had to deal with these engineering problems in addition to building your business.

Technology today evolves much faster than in 2006. That is partly because managed cloud services make operating a software company so much smoother. You can build faster, iterate faster, and there are fewer outages.

If you are an insurance company or a t-shirt manufacturing company or an online education platform, software engineering is undifferentiated heavy lifting. Your customers are not paying you for your expertise in databases or your ability to configure load balancers. As a business, you should be focused on what the customers are paying you for, and spending the minimal amount of time on rebuilding software that is available as a commodity cloud service.

Rich Archbold is the director of engineering at Intercom, a rapidly growing software company that allows for communication between customers and businesses. At Intercom, the engineering teams have adopted a philosophy called Run Less Software.

Running less software means reducing choices among engineering teams, and standardizing on technologies wherever possible.

When Intercom was in its early days, the systems were more heterogeneous. Different teams could choose whatever relational database they wanted–MySQL or Postgres. They could choose whatever key/value store they were most comfortable with.

The downside of all this choice was that engineers who moved from one team to another team might not know how to use the tools at the new team they were moving to. After switching teams, you would have to figure out how to onboard with those new tools, and that onboarding process was time that was not spent on effort that impacted the business.

By reducing the number of different choices that engineering teams have, and opting for managed services wherever possible, Intercom ships code at an extremely fast pace with very few outages. In our conversation, Rich contrasts his experience at Intercom with his experiences working at Amazon Web Services and Facebook.

Amazon and Facebook were built in a time where there was not a wealth of managed services to choose from, and this discussion was a reminder of how much software engineering has changed because of cloud computing.

To learn more about Intercom, you can check out the Inside Intercom podcast.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Run Less Software with Rich Archbold", + "Episodes Uid": "SED3079678313", + "Episodes Audio File": "800ee8b744a88625929b94e60407bb20.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3d3", + "Episodes ID": "f4ec6d86-e328-11ea-91a2-e757a16a0a03", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/IstioMotivations.mp3", + "Episodes Pubdate Date": "2018-01-09", + "Episodes Summary": "

A single user request hits Google’s servers. A user is looking for search results.

In order to deliver those search results, that request will have to hit several different internal services on the way to getting a response.

These different services work together to satisfy the user request. All of these services need to communicate efficiently, they need to scale, and they need to be secure. Services need to have a consistent way of being “observable”–allowing logging and monitoring. Services need to have proper security.

Since every service wants these different features (like communication, load balancing, security), it makes sense to build these features into a common system that can be deployed to every server.

Louis Ryan has spent his years at Google working on service infrastructure. During that time, he has seen massive changes in the way traffic flows through Google. First, the rise of Android, and all of the user traffic from mobile phones. And second, the rise of Google Cloud Platform, which meant that Google was now responsible for nodes deployed by users outside of Google.

These two changes–mobile and cloud–led to an increase in the amount of traffic and the type of traffic. All of this traffic leads to more internal services communicating with each other. How does service networking change in such an environment?

Google’s adaptation to the new networking conditions is to introduce a “service mesh”. A service mesh is a network for services. It provides observability, resiliency, traffic control, and other features to every service that plugs into it.

Each service needs to plug into the service mesh. In Kubernetes, services connect to the mesh through a sidecar. Let me explain the term “sidecar.”

Kubernetes manages its resources in pods, and each pod contains a set of containers. You might have a pod that is dedicated to responding to any user that is requesting a picture of a cat. Within that pod, you not only have the container that serves the cat picture–you also have other “sidecar” containers that help out an application container.

You could have a sidecar that gets deployed next to your application container that handles logging, or a sidecar that helps out with monitoring, or network communications.

If you are using the Istio service mesh, that means that you are using a sidecar called Envoy. Envoy is a sidecar called a “service proxy” that provides configuration updates, load balancing, proxying, and lots of other benefits. If we get all that out of Envoy, why do we need a separate abstraction of a “service mesh”? Because it helps to have a tool that aggregates and centralizes all the different communications among these proxies.

Every service gets a sidecar for a service proxy. Every service proxy communicates with the centralized service mesh.

Louis Ryan joins this episode to explain the motivations for building the Istio service mesh, and the problems it solves for Kubernetes developers.

For the next two weeks, we are covering exclusively the world of Kubernetes. Kubernetes is a project that is likely to have as much impact as Linux–and it is very early days. Whether you are an expert in Kubernetes or you are just starting out, we have lots of episodes to fit your learning curve. To find all of our old episodes about Kubernetes (including a previous show about Istio), download the Software Engineering Daily app for iOS or for Android. In other podcast players, only the most 100 recent episodes are available, but in our apps you can find all 650 episodes–and there is also plenty of content that is totally unrelated to Kubernetes!

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Istio Motivations with Louis Ryan", + "Episodes Uid": "SED7085970857", + "Episodes Audio File": "0dbfd91cca57c06a21edb989aee5732d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "37x", + "Episodes ID": "f5a24020-e328-11ea-91a2-7fb58d769e0f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ServerlessEvents.mp3", + "Episodes Pubdate Date": "2017-11-14", + "Episodes Summary": "

In an event driven application, each component of application logic emits events, which other parts of the application respond to. We have examined this pattern in previous shows that focus on pub/sub messaging, event sourcing, and CQRS.

In today’s show, we examine the intersection of event driven architecture and serverless architecture.

Serverless applications can be built by combining functions-as-a-service (like AWS Lambda) together with backend as a service tools like DynamoDB and Auth0. Functions-as-a-service give you cheap, flexible, scalable compute. Backend as a service tools give you robust, fault-tolerant tools for managing state.

By combining these sets of tools, we can build applications without thinking about specific servers that are managing large portions of our application logic. This is great–because managing servers and doing load balancing and scaling is painful.

With this shift in architecture, we also have to change how data flows through our applications.

Danilo Poccia is the author of AWS Lambda In Action, a book about building event-driven serverless applications. In today’s episode, Danilo and I discuss the connection between serverless architecture and event driven architecture.

We start by reviewing the evolution of the runtime unit–from physical machines to virtual machines to containers to functions as a service. Then, we dive into what it means for an application to be “event driven.” We explore how to architect and scale a serverless architecture, and we finish by discussing the future of serverless–how IoT and edge computing and on-premise architectures will take advantage of this new technology.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless Event-Driven Architecture with Danilo Poccia", + "Episodes Uid": "SED4864402378", + "Episodes Audio File": "7b69e93c434f9f8156cf406fc2714114.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2qh", + "Episodes ID": "facc8952-e328-11ea-91a2-2328330a5cbf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RelayModern.mp3", + "Episodes Pubdate Date": "2017-05-24", + "Episodes Summary": "

Relay is a JavaScript framework for building data-driven React applications. Facebook open sourced Relay around the same time they open sourced GraphQL, and Facebook expected Relay to be the more popular of the two projects.

However, the reality was reversed. Open source companies like Meteor quickly began to build GraphQL tools and a few businesses were started around GraphQL. One year later, the excitement for GraphQL had completely surpassed the excitement for Relay which had aged poorly in a newborn ecosystem of GraphQL tooling.

At the same time, Facebook was also starting to integrate Relay into their React Native apps. But Relay was performing poorly on low-end Android devices. This led the Relay team to the conclusion that they needed to rewrite Relay. Both to better fit into the growing GraphQL ecosystem, and to be built with performance in low-end React Native environments at the top of mind.

Relay Modern is the new version of Relay. It was released to the open source community at this year’s F8. In this episode Caleb Meredith is joined by Lee Byron, the co-creator of GraphQL, and Joe Savona, a founding member of the Relay team, to discuss Relay Modern. The discussion includes a conversation about the commercial GraphQL ecosystem, the story of why Facebook decided Relay needed to be rewritten, and a look at the future of UI development from some trends seen in Relay Modern.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

Sponsors

", + "Episodes Title": "Relay Modern with Lee Byron and Joe Savona", + "Episodes Uid": "SED1336021834", + "Episodes Audio File": "194b247420c110d4bde22f1de12f201b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "xz", + "Episodes ID": "2ccdc4ac-e329-11ea-91a2-b77d170333a8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Flink_Edited_leveled.mp3", + "Episodes Pubdate Date": "2015-11-11", + "Episodes Summary": "

Apache Flink is an open-source framework for distributed stream and batch data processing.

Stephan Ewen is a committer and PMC member of the Flink project, and the CTO of Data Artisans.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Apache Flink with Stephan Ewen", + "Episodes Uid": "SED8407914837", + "Episodes Audio File": "62bdd2f0053e0ceeec73763f2d5b5a3d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yq", + "Episodes ID": "f6b58cf6-e328-11ea-91a2-e36cdc5cb099", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CloudNativeSQL.mp3", + "Episodes Pubdate Date": "2017-08-28", + "Episodes Summary": "

Applications built in the cloud are often serving requests from all around the world. A user in Hong Kong could have written to a database entry at the moment just before a user in San Francisco and a user in Germany simultaneously try to read from that database. If the user in San Francisco is allowed to see a different database entry than the user in Germany, that database is not strongly consistent.

Strongly consistent databases work such that two users who read the same entry at the same time will receive the same result. Weakly consistent or “eventual consistent” databases are suitable for applications where transaction ordering is not important–photo sharing apps and ecommerce shopping carts, for example. Bank accounts, on the other hand, often need to be strongly consistent.

CockroachDB is a scalable, survivable, strongly consistent database. Alex Robinson is an engineer at Cockroach Labs and he joins the show to explain the data model for CockroachDB and how it maintains strong consistency.

", + "Episodes Title": "Cloud-Native SQL with Alex Robinson", + "Episodes Uid": "SED6772014884", + "Episodes Audio File": "2b89c048568aa42311ece05af37f92a1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4ev", + "Episodes ID": "f1606082-e328-11ea-91a2-3708ae514fee", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_13_EnterpriseKuberneteswithChrisGaun.mp3", + "Episodes Pubdate Date": "2018-09-13", + "Episodes Summary": "

A company runs a variety of distributed systems applications such as Hadoop for batch processing jobs, Spark for data science, and Kubernetes for container management. These distributed systems tools can run on-prem, in a cloud provider, or in a hybrid system that uses on-prem and cloud infrastructure. Some enterprises use VMs, some use bare metal, some use both.

Mesosphere is a company that was started to abstract the complexity of resource management away from the application developer. Instead of a developer managing virtual machines, provisioning cloud infrastructure, or wiring all that infrastructure together to run distributed applications, the developer spins up distributed applications like Kubernetes, Spark, or Jenkins on top of Mesosphere, and Mesosphere provisions the machines on the underlying infrastructure.

Using Kubernetes on top of Mesos allows you to separate resource provisioning from the actual container orchestration. In a previous episode, we explored how Netflix uses Mesos with a container orchestrator on top to simplify the resource management of microservice application containers as well as data science workloads.

Chris Gaun is a product manager at Mesosphere who helped build Kubernetes-as-a-service. In today’s show, he describes why it is useful to have separate layers for resource provisioning and container orchestration. He also talks about the difficulties of manually installing Kubernetes, and why Mesosphere built a Kubernetes-as-a-service product. Full disclosure: Mesosphere is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Orchestrating Kubernetes with Chris Gaun", + "Episodes Uid": "SED5579481757", + "Episodes Audio File": "2edffa11ace1d81b5a7e033f8955b1c5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 490, + "Episodes ID": "f2006aaa-e328-11ea-91a2-6f76245d62ed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_01_CastorEDC.mp3", + "Episodes Pubdate Date": "2018-08-01", + "Episodes Summary": "

Medical breakthroughs require medical research. Medical research requires patient testing and data collection. The most common form of capturing patient data is through surveys–and most of those surveys today are done on paper.

Surveying patients to understand the side effects or benefits of trial drugs or treatments, and getting accurate results out of these are critical aspects of medical research. Traditionally, these surveys are filled and read manually, and entered into a database by a human operator. In these steps, there is too much room for human error, from unreadable handwritings to typos being entered into the databas

Electronic Data Capture platforms were created out of this need for easy and accurate data collection for researches. By enabling online survey creation and result collection, EDC platforms improved medical research immensely.

However, these platforms are complex to design. Where patient medical data is concerned, privacy and security are of extremely high importance. Compliance with laws that protect anonymity and privacy of the patients is necessary. On top of these, the platform must be easy-to-use, and reliable.

Castor EDC is a company specializing on EDC for medical research, founded in the Netherlands and active in many countries around the globe. Our guest today is Derk Arts, the founder and CEO of Castor EDC.

In this episode we discuss Electronic Data Capture platforms, how Castor EDC overcame the engineering and design problems, how they comply with the laws, and their business model.

", + "Episodes Title": "Castor EDC with Derk Arts", + "Episodes Uid": "SED7169768584", + "Episodes Audio File": "4cab8c8e5f2bdf5c288ac05bbd8d88c1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "41q", + "Episodes ID": "f270ca02-e328-11ea-91a2-d360f3f52bb9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_28_Chromium.mp3", + "Episodes Pubdate Date": "2018-06-28", + "Episodes Summary": "

Chromium is an open source browser that shares code with the Chrome browser from Google. A browser is a large piece of software, with engineering challenges around threading, rendering, resource management, and networking. To add to the complexity, Chrome runs on iOS, Android, MacOSX, Windows, and other platforms.

Chrome OS is an operating system based on Chrome. There is also Chromium OS, the open source version of Chrome OS. The Chrome/Chromium operating systems are based off of Linux.

Through this entire episode, the line between browser and operating system is blurry. There is so much resource management involved in the Chrome browser that it has its own task manager. For many people (including myself) the browser is the main application you are interfacing with throughout the day. It handles all of your business applications. Even many of your desktop apps, such as Slack, are running on Electron, which is a framework for building cross-platform apps that uses Chromium.

David Bokan is an engineer on the Chromium team at Google, and he joins the show to describe the engineering of Chrome and the development and release process. David also gives his thoughts on future developments for browsers, apps, and the Internet.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Chrome and Chromium with David Bokan", + "Episodes Uid": "SED9947107256", + "Episodes Audio File": "41fb8d358065db509b533ef7e12d3cc2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3r0", + "Episodes ID": "f31f3a74-e328-11ea-91a2-3bf1140dcad6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_10_DeepLearningTopologies.mp3", + "Episodes Pubdate Date": "2018-05-10", + "Episodes Summary": "

Algorithms for building neural networks have existed for decades. For a long time, neural networks were not widely used. Recent changes to the cost of compute and the size of our data have made neural networks extremely useful. Our smart phones generate terabytes of useful data. Lower storage costs make it economical to keep that data. Cloud computing democratized the ability to do large scale machine learning across GPUs.

Over the last few years, these trends have been driving widespread use of deep learning, in which neural nets with a large series of layers are used to create powerful results in various fields of classification and prediction. Neural networks are a tool for making sense of unstructured data–text, images, sound waves, and videos.

“Unstructured” data is data with high volume or high dimensionality. For example, an image has a huge collection of pixels, and each pixel has a color value. One way to think about image classification is that you are finding correlations between those pixels. A certain cluster of pixels might represent an edge. After doing edge detection on pixels, you have a collection of edges. Then you can find correlations between those edges, and build up higher levels of abstraction.

Yinyin Liu is a principal engineer and head of data science at the Intel AI products group. She studies techniques for building neural networks. Each different configuration of a neural network for a given problem is called a “topology.” Engineers are always looking at new topologies for solving a deep learning application–such as natural language processing.

In this episode, Yinyin describes what a deep learning topology is and describes topologies for natural language processing. We also talk about the opportunities and the bottlenecks in deep learning–including why the tools are so immature, and what it will take to make the tooling better.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Deep Learning Topologies with Yinyin Liu", + "Episodes Uid": "SED2826340177", + "Episodes Audio File": "5e749d09e76cdf7ca867577d0a102aff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5wh", + "Episodes ID": "ed6bcc1e-e328-11ea-91a2-5f9167cef948", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_03_PermissionlessInnovation.mp3", + "Episodes Pubdate Date": "2019-07-03", + "Episodes Summary": "

Open source software allows developers to take code from the Internet and modify it for their own use. Open source has allowed innovation to occur on a massive scale. Today, open source software powers our consumer client applications and our backend cloud server infrastructure. 

Linux powers single node operating systems and Kubernetes is the foundation for new distributed systems. Hadoop created an open source distributed file system, Spark gave us a computational runtime on top of it, and Kafka created a middleware platform for shuttling data from one place to another.

There are numerous other examples of how open source has changed the world of software development. Open source has also reshaped the business landscape of infrastructure software companies. 

A common business structure for a modern infrastructure company is the “open core” model. An open core company maintains an open source project that is free to use, but also sells a product or service around that product. Companies with an open core model include Red Hat, HashiCorp, and GitLab.

Many companies are building a thriving business with the open core business model. But these companies do not directly control the most important part of the infrastructure supply chain: the cloud provider.

Cloud providers have a fundamental tension with open core companies because the cloud providers offer services that compete with the open core companies. 

In addition to the issue of cloud providers competing directly with the open core companies, some people have questioned whether Amazon Web Services is capturing an unfair portion of the value that is being created by open source.

Amazon Web Services is the biggest cloud provider, and it has built a large catalog of services that are built off of open source software. But AWS has not historically contributed heavily to open source relative to the value it has captured. 

One example of an open core company which has lost market share to an AWS cloud-hosted offering is Elastic, the open core company which maintains the ElasticSearch open source project. Amazon ElasticSearch Service is a closed-source hosted offering built on top of the ElasticSearch.

Elastic (the company) has increasingly intermingled proprietary software with their open source repository, making it less clear how that open source repository can be used by companies that want to deploy it for their commercial use.

Open core companies such as MongoDB, Redis Labs, and Cockroach Labs have responded to the competitive pressures of AWS by changing their licenses and making it more expensive for cloud providers to offer a cloud-hosted offering of their open source project.

The dynamics between cloud providers and open core companies will continue to evolve in the coming years. The norms around open source are up for debate.

Joseph Jacks is the founder of OSS Capital, a venture firm focused on investments in commercial open source software companies. He returns to the show to discuss the changing landscape of open core companies, and the benefits of permissionless innovation.

", + "Episodes Title": "Permissionless Innovation with Joseph Jacks", + "Episodes Uid": "SED3719327577", + "Episodes Audio File": "10b08ad2bdf88f4164ece290cf55279d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "65a", + "Episodes ID": "ec8cb4ca-e328-11ea-91a2-dba94a98af4a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_03_DeltaAirlines.mp3", + "Episodes Pubdate Date": "2019-09-03", + "Episodes Summary": "

Airlines have always had an emphasis on new technology. Over the years, airlines have needed to develop more and more software. Digital transformation is causing every large company to adopt the tools and practices of software companies, and that includes Delta Airlines.

Delta Airlines has existed for more than 90 years. Over that period of time, the company has developed new systems in every generation of software, from the days of mainframe computers to a modern Java-based backend. When the DevOps movement started to take shape, Delta Airlines started to take a more focused approach on continuous integration, version control, and an organizational structure that removed silos between teams.

Jasmine James is a manager at Delta Airlines where she focuses on improving the software practices of the company. She joins the show to talk through the process of changing the developer culture within Delta, as well as what it is like to build software for an airline. Jasmine is speaking at GitLab Commit in Brooklyn on September 17, 2019, and GitLab is a sponsor of Software Engineering Daily, so if you are thinking about attending GitLab Commit, you can go to softwareengineeringdaily.com/commit and enter code COMMITSED to save 30% on your ticket, while also supporting Software Engineering Daily.

", + "Episodes Title": "DevOps at Delta Air Lines with Jasmine James", + "Episodes Uid": "SED9023698780", + "Episodes Audio File": "13d4b4fc8340b2e64f0c5058dfa70450.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5nu", + "Episodes ID": "ee3acb22-e328-11ea-91a2-37432ae329db", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_03_SatelliteDataBroker.mp3", + "Episodes Pubdate Date": "2019-05-03", + "Episodes Summary": "

Satellite images contain vast quantities of data. By analyzing the contents of satellite images over time, we can identify trends in weather, soil, and agriculture. If we combine that data with ground-level sensors, we can gather a clearer understanding of how chemicals in the air or in the dirt map to how things look from above via satellite.

Descartes Labs is a company that gathers high dimensional data about our planet and turns it into machine learning models to be used by customers. In order to do this, the company has built out a data pipeline involving queueing systems, machine learning frameworks, and internal tools that are used to aggregate, clean, model, and measure data.

Tim Kelton is a co-founder of Descartes Labs and he joins the show to discuss the high volume of data and the distributed systems that make up the Descartes Labs infrastructure.

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Satellite Data Platform with Tim Kelton", + "Episodes Uid": "SED2070329061", + "Episodes Audio File": "a74ed769ff099dd228a3223962fad68f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "v3", + "Episodes ID": "2e775912-e329-11ea-91a2-c74c465aa8c6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/turing_school_final.mp3", + "Episodes Pubdate Date": "2015-10-26", + "Episodes Summary": "

Steve Kinney is the co-director of academics at Turing School of Software and Design.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Turing School with Steve Kinney", + "Episodes Uid": "SED3544991590", + "Episodes Audio File": "670e0b45d90cbd1acc3bf9ddb5a11c06.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "64c", + "Episodes ID": "ec9e2e94-e328-11ea-91a2-cf3360d77167", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_27_FacebookReleaseEngineering.mp3", + "Episodes Pubdate Date": "2019-08-27", + "Episodes Summary": "

When Chuck Rossi joined Facebook in 2008, he was one of the most experienced release engineers at the company. As he began to explore the engineering practices of the organization, he was surprised, confused, and impressed by the release engineering system that he encountered.

Release engineering is the process by which software is released to users. As software is being developed, it moves through a series of testing environments. In these test environments, the software can be studied using simulated inputs that can help developers discover software bugs.

Chuck had come to Facebook from Google. At Google, the crown jewel was Google web search which had a regimented release process. At Facebook, the crown jewel was facebook.com. Chuck found that the release process for facebook.com was much different than Google web search.

Chuck joins the show to talk about release engineering at Facebook, and how the company constantly evolved its code deployment process. Chuck also describes Facebook’s pivot to mobile, and how the bottlenecks in the mobile app release process threatened Facebook’s ability to iterate and release quickly.

This show provided some amazing perspective on continuous delivery, and will be useful to anyone who is working on figuring out their “DevOps” process. Chuck has a wealth of knowledge and context about the modern software industry.

", + "Episodes Title": "Facebook Release Engineering with Chuck Rossi", + "Episodes Uid": "SED2437765411", + "Episodes Audio File": "cfde709589e8c6c046fa88f77792cef6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3h5", + "Episodes ID": "f44b3f2e-e328-11ea-91a2-97ecd23c309e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_16_FlinkandVideo.mp3", + "Episodes Pubdate Date": "2018-02-16", + "Episodes Summary": "

When you go to a website where a video is playing, and your video lags, how does the website know that you are having a bad experience?

Problems with video are often not complete failures–maybe part of the video loads, and plays just fine, and then the rest of the video is buffering. You have probably experienced sitting in front of a video, waiting for it to load as the loading wheel mysteriously spins.

Since problems with video are often not complete failures, troubleshooting a problem with a user’s video playback is not as straightforward as just logging whenever a crash occurs. You need to continuously monitor the video playback on every client device and aggregate it in a centralized system for analysis.

The centralized logging system will allow you to separate problems with a specific user from problems with the video service itself. A single user could have bad wifi, or have 50 tabs open with different videos. To identify problems that are caused by the video player rather than the user, you need to capture the playback from every video and every user.

Scott Kidder works at Mux, where he builds a streaming analytics system for video monitoring. In this episode, Scott explains how events make it from a video player onto the backend analytics system running on Kinesis and Apache Flink.

Events from the browser are constantly added to Kinesis (which is much like Kafka). Apache Flink reads those events off of Kinesis and map reduces them to discover anomalies. For example, if 100 users watch a 20 minute cat video, and the video stops playing at minute 12 for all 100 users, there is probably some data corruption in that video. You would only be able to discover that by assessing all users.

Scott and I discussed the streaming infrastructure that he works on at Mux, as well as other streaming systems like Spark, Apache Beam, and Kafka.

This episode is the first in a short series about streaming data infrastructure. I wanted to do some shows in preparation for Strata Data conference in March in San Jose, which I will be attending thanks to a complimentary ticket from O’Reilly. O’Reilly has been kind enough to give me free tickets since Software Engineering Daily started and did not have the money to attend any conferences. If you want to attend Strata, you can use promo code PCSED to get 20% off.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Streaming Analytics with Scott Kidder", + "Episodes Uid": "SED9930888078", + "Episodes Audio File": "cb7d129f5bd87634bcfe1c81ebd3432c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4v1", + "Episodes ID": "f0b3705c-e328-11ea-91a2-1b149cf2ea79", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_2_ScalingLyft.mp3", + "Episodes Pubdate Date": "2018-11-02", + "Episodes Summary": "

Matt Klein has worked for three rapidly growing Internet companies. At AWS, he worked on EC2, the compute-as-a-service product that powers a large percentage of the Internet. At Twitter, he helped scale the infrastructure in the chaotic days before Twitter’s IPO. Today he works at Lyft, building systems to allow for ride sharing infrastructure to work more safely and reliably.

Hypergrowth Internet companies are faced with quickly growing demands on their software. The demands on the software expose problems with the core infrastructure. Simultaneously, the company tries to ramp up its hiring process. More engineers get hired, and the institutional knowledge within the company starts to weaken. Documentation gets out of date. Senior engineers burn out and leave the company.

When a company starts growing quickly, communications can break down. A hypergrowth company can suffer from a lack of “human scalability”. Matt Klein has observed these challenges at AWS, Twitter, and Lyft. In his article “The Human Scalability of ‘DevOps’”, he explains why these problems manifest and what can be done to alleviate them.

In a previous show, Matt discussed the engineering challenges at Lyft that led him to create Envoy, a service proxy. This episode covers some broad technical topics–DevOps, site reliability engineering, platform engineering–but the episode is mostly about how a hypergrowth company can manage culture, hiring, and engineering organization.

Matt is a very fun guest to have because he questions some of the strange practices that have been widely adopted by successful companies. Internet companies are a very new phenomenon, and the management tactics that they have adopted are not well proven–so it is great to have someone like Matt provide a fresh perspective on ways that companies can scale their technology and their organization more effectively.

", + "Episodes Title": "Scaling Lyft with Matt Klein", + "Episodes Uid": "SED9962529190", + "Episodes Audio File": "0251438ae6ec5fcf40c3f9c383cc00eb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "38u", + "Episodes ID": "f57f78d8-e328-11ea-91a2-3b9f1969b0e9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ThumbtackMarketplaceEvolution.mp3", + "Episodes Pubdate Date": "2017-11-27", + "Episodes Summary": "

The labor market is moving online.

Taxi drivers are joining Uber and Lyft. Digital freelancers are selling their services through Fiverr. Experienced software contractors are leaving contract agencies to join Gigster. Online labor marketplaces create market efficiency by improving the communications between buyers and sellers. Workers make their own hours, and their performance is judged by customers and algorithms, rather than the skewed perspective of a human manager.

These marketplaces for human labor are in different verticals, but they share a common problem: how do you most efficiently match supply and demand?

Perfect marketplace matching is an unsolved problem. Hundreds of computer science papers have been written about the problems of stable matching, which often turn out to be NP-Complete. The stock market has been attempting to automate marketplace matching for decades, and inefficiencies are discovered every year.

Today’s show is about matching buyers and sellers on Thumbtack, a marketplace for local services.

For the first seven years, Thumbtack was building liquidity in its 2-sided market. During those years, the model for job requests was as follows: let’s say I was on Thumbtack looking for someone to paint my house. I would post a job that would say I am looking for house painters. The workers on Thumbtack that paint houses could see my job and place a bid on it. Then I would choose from the bids and get my house painted.

This was the “asynchronous” model. The actions of the buyer and seller were not synchronized. There was a significant delay between the time when the buyer posted a job and the time when a seller places a bid, and then another delay before the buyer selects from the sellers.

Thumbtack recently moved to an “instant matching” model. After gathering data about the people selling services on the platform, Thumbtack is now able to avoid the asynchronous bidding process. In the new experience, a buyer goes on the platform, requests a house painter, and is instantly matched to someone who has a history of accepting house painting tasks that fit the parameters of the buyer.

From the user’s perspective, this is a simple improvement. From Thumbtack’s perspective, there was significant architectural change required. In the asynchronous model, the user requests lined up in a queue, and were matched with pros who placed bids on the items in that queue. In the instant matching model, a user request became more like a search query–the parameters of that request hit an index of pros and returns a response immediately.

Xing Chen is an engineer from Thumbtack, and joins the show to describe the rearchitecture process–how Thumbtack went from an asynchronous matching system to synchronous, instant matching. We also explore some of the other architectural themes of Thumbtack, which we dive into in further detail in tomorrow’s episode about scaling Thumbtack’s infrastructure, which uses both AWS and Google Cloud.

On Software Engineering Daily, we have explored the software architecture and business models of different labor marketplaces–from Uber to Fiverr. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Marketplace Matching with Xing Chen", + "Episodes Uid": "SED4660220201", + "Episodes Audio File": "56415cd9827c24fac35b3b27dafa6f2d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3me", + "Episodes ID": "f3ab6b2a-e328-11ea-91a2-fb4d9eac45c6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_03_Gitcoin.mp3", + "Episodes Pubdate Date": "2018-04-03", + "Episodes Summary": "

Most technology companies rely on open source software projects. But open source software projects are often maintained by a group of people that is not affiliated with any particular company. When an open source project develops too much technical debt, it can become a tragedy of the commons. Who is responsible for maintaining these open source projects?

This is the motivation for open source bounties. Companies and individuals who rely on open source create bounties, which are financial incentives for developers to solve problems within the open source project.

Kevin Owocki is the creator of Gitcoin, a platform for open source bounties that is mediated by an Ethereum smart contract. Kevin joins the show to discuss his experience building Gitcoin–as well as some of the problems with the blockchain space, such as rampant ICOs. Gitcoin is NOT a cryptocurrency or token itself–it is a platform for open source software to be built more efficiently. Kevin was an awesome guest and you will enjoy the conversation.

Gitcoin is a nice example of a real-world Ethereum use case–it uses Ethereum for escrow: if I post a $25 bounty for someone to fix a bug in my open source project, I will lock up ether in a smart contract. When the bug is fixed, the programmer who fixed it will submit a pull request on Github, and I will release the ether from the smart contract to pay them.

We would love for you to fill out our listener survey at softwareengineeringdaily.com/survey. This will help us decide what other content to focus on.

Of course–you can also send me an email at any time, jeff@softwaredaily.com. And in the meantime, if you are completely sick of cryptocurrencies, check out our back catalog of episodes at softwaredaily.com, or by downloading our Software Engineering Daily apps, which have all of our episodes including our Greatest Hits, which is a curated set of the most popular shows. The apps will soon have offline downloads and bookmarking.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Gitcoin: Open Source Bounties with Kevin Owocki", + "Episodes Uid": "SED1938698371", + "Episodes Audio File": "c0653cc35bc4dc46913902a28d4e7c34.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5n1", + "Episodes ID": "ee627b7c-e328-11ea-91a2-97023d705e66", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_24_Gvisor.mp3", + "Episodes Pubdate Date": "2019-04-24", + "Episodes Summary": "

RECENT UPDATES:

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat.

The Linux operating system includes user space and kernel space. In user space, the user can create and interact with a variety of applications directly. In kernel space, the Linux kernel provides a stable environment in which device drivers interact with hardware and manage low level resources.

A Linux container is a virtualized environment that runs within user space.  To perform an operation, a process in a container in user space makes a syscall (system call) into kernel space. This allows the container to have access to resources like memory and disk.

Kernel space must be kept secure to ensure operating system integrity–but Linux includes hundreds of syscalls. Each syscall represents an interface between the user space and kernel space. Security vulnerabilities can emerge from this wide attack surface of different syscalls, and most applications only need a small number of syscalls to perform their required functionality.

gVisor is a project to restrict the number of syscalls that the kernel and user space need to communicate. gVisor is a runtime layer between the user space container and the kernel space. gVisor reduces the number of syscalls that can be made into kernel space.

The security properties of gVisor make it an exciting project today–but it is the portability features of gVisor that hint at a huge future opportunity. By inserting an interpreter interface between containers and the Linux kernel, gVisor presents the container world with the opportunity to run on operating systems other than Linux.

There are many reasons why it might be appealing to run containers on an operating system other than Linux.

Linux was built many years ago, before the explosion of small devices, smart phones, IoT hubs, voice assistants and smart cars. To be more speculative, Google is working on a secretive new operating system called Fuscia. gVisor could be a layer that allows workloads to be ported from Linux servers to Fuscia servers.

Yoshi Tamura is a product manager at Google with a background in containers and virtualization. He joins the show to talk about gVisor and the different kinds of virtualization.

", + "Episodes Title": "gVisor: Secure Container Sandbox with Yoshi Tamura", + "Episodes Uid": "SED6594559997", + "Episodes Audio File": "8618a0c7ddb7a80a9a01cbf4d44f34ba.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7c7", + "Episodes ID": "e8d76672-e328-11ea-91a2-9fc2afb92a2f", + "Episodes Original URL": "https://sd-profile-pictures.s3-us-west-2.amazonaws.com/adfree/fb_oss_edited_fixed_adfree.mp3", + "Episodes Pubdate Date": "2020-06-19", + "Episodes Summary": "

Originally published April 14, 2017. We are taking a few weeks off. We’ll be back soon with new episodes.

Facebook’s open source projects include React, GraphQL, and Cassandra. These projects are key pieces of infrastructure used by thousands of developers–including engineers at Facebook itself.

These projects are able to gain traction because Facebook takes time to decouple the projects from their internal infrastructure and clean up the code before releasing them into the wild. Facebook has high standards for what they are willing to release.

Tom Occhino manages the React team at Facebook and works closely with engineers to determine what projects make sense to open source. In this episode, Preethi Kasireddy interviews Tom about how Facebook thinks about open source–what went right with React, why it makes sense for Facebook to continue to release new open source projects, and how full-time employees at Facebook interact with that open source codebase.

", + "Episodes Title": "Facebook Open Source with Tom Occhino (Summer Break Repeat)", + "Episodes Uid": "SED7571359233", + "Episodes Audio File": "ac6258d28b554e9b4f313266dada6f58.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3wh", + "Episodes ID": "f2d8242c-e328-11ea-91a2-cbe8b185324a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_31_Benchling.mp3", + "Episodes Pubdate Date": "2018-05-31", + "Episodes Summary": "

Ten years ago, a biology researcher was limited by the software tools available. Most of the electronic record keeping was done using Excel and other general purpose tools. Benchling is a suite of software tools that were designed to simplify the lives of life science researchers. Benchling helps with sample tracking, experiment design, and workflow management.

Sherwin Yu is an engineering manager at Benchling, and he joins the show to discuss the workflows of the life scientist–how experiments are designed and managed. Life science researchers in both academia and industry use Benchling, and Sherwin spends time talking to them and understanding what they need from their tools. We also talked about the impact of CRISPR, robotic cloud laboratories, and other future developments.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Life Science R&D with Sherwin Yu", + "Episodes Uid": "SED9771586870", + "Episodes Audio File": "cb7e3961bc9c5e9208253e1ef3eda7cb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 605, + "Episodes ID": "eceb369e-e328-11ea-91a2-9366eec65528", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_05_GoldenKnowledgeAIPlatform.mp3", + "Episodes Pubdate Date": "2019-08-05", + "Episodes Summary": "

A knowledge base assembles information from a wide variety of sources into a central platform.

The most popular knowledge base is Wikipedia, which covers a wide variety of concepts through a system that attempts to remain authoritative and impartial. Other open knowledge platforms include Stack Overflow, which focuses on programming concepts, and Quora, which adds a social element to the process of information accumulation.

Golden.com is a knowledge base that indexes, categorizes, and surfaces information. Golden has information about software, genetics, world history, social media, sports, and all kinds of other subjects. The company monetizes with a paid knowledge base product for enterprises, which allows for easy easy querying of the open knowledge base and a private knowledge base for internal information.

Jude Gomila is the founder of Golden, and joins the show to discuss the process of building a universal knowledge base, and the engineering problems that he is working on to improve Golden.

", + "Episodes Title": "Golden: Intelligent Knowledge Map with Jude Gomila", + "Episodes Uid": "SED3082471104", + "Episodes Audio File": "b633fe4b4f81737fa86ac8666cc7746c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3r1", + "Episodes ID": "f31a9e10-e328-11ea-91a2-4791ecdd9ef0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_11_Mesosphere.mp3", + "Episodes Pubdate Date": "2018-05-11", + "Episodes Summary": "

Mesos is a system for managing distributed systems. The goal of Mesos is to help engineers orchestrate resources among multi-node applications like Spark. Mesos can also manage lower level schedulers like Kubernetes. A common misconception is that Mesos aims to solve the same problem as Kubernetes, but Mesos is a higher level abstraction.

Ben Hindman co-founded Mesosphere to bring the Mesos project to market. Large enterprises like Uber, Netflix, and Yelp use Mesosphere for resource management. Before he started the company, Ben worked in the Berkeley AMP Lab, a research program where the Spark and Tachyon projects were also born.

At this point, he has spent significant time in both academia and industry. This conversation spans distributed systems theory, history, and practice. Ben and I spoke at KubeCon 2018 in Copenhagen–which was an amazing conference. We were both amazed at how big the audience for Kubernetes has gotten, and the pace at which the technology is advancing.

Today, Kubernetes is mostly used for scheduling containerized applications that engineers have built themselves. But there will be higher level tools that use Kubernetes as a building block. Much like Zookeeper was used as a building block for Hadoop, Kubernetes will be used to build serverless applications and distributed databases.

Once you are using a distributed database built on Kubernetes, you don’t want to think about the container orchestration–you want to think about the raw storage and CPU requirements for that database. This is one reason why Mesos is so compelling. Since Kubernetes creates an increased cardinality of distributed systems, it’s good to know that there is a framework built to manage those higher level applications.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cluster Schedulers with Ben Hindman", + "Episodes Uid": "SED2249928631", + "Episodes Audio File": "3ef10c50b9bcf82afb7d82d59d344b1f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2sx", + "Episodes ID": "f988ecac-e328-11ea-91a2-ab9af6bba34e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/kubeless_edited.mp3", + "Episodes Pubdate Date": "2017-06-13", + "Episodes Summary": "

Modern architectures often consist of containers that run services. Those containers scale up and down depending on the demand for the services. These large software systems often use a technique known as event sourcing, where every change to the system is kept in an event log. When an event on the log is processed, several different data stores might be updated in response.

In these architectures, containers are interacting with each other. Multiple databases are responding to events in the event log. To connect these systems together, engineers can write small functions to pass data around–you might call these small connecting functions “glue.” Glue functions are a great use for a serverless tool such as AWS Lambda or Google Cloud Functions. As these glue functions grow in popularity, there is an increased need for an open source way to deploy serverless functions.

Sebastian Goasgoen works on Kubeless, a serverless execution tool built on top of Kubernetes. In this episode, we explore his take on the “serverless on Kubernetes” problem. This is a great companion episode to yesterday’s interview with Soam Vasani.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

", + "Episodes Title": "Event Driven Serverless with Sebastian Goasgoen", + "Episodes Uid": "SED8496361072", + "Episodes Audio File": "30d2d41b1c68025a70e22a763d7115a6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yo", + "Episodes ID": "f6be62cc-e328-11ea-91a2-53c831c421c7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/HeaderBidding.mp3", + "Episodes Pubdate Date": "2017-08-24", + "Episodes Summary": "

Content websites are supported by advertising. Most of the advertisements around the internet are dynamic ad slots that change depending on the user who visits the site. Those dynamic ad slots are available to a variety of different bidders. For each ad slot, an auction occurs. The highest bidder gets to serve an ad for that slot.

Praneet Sharma is the co-founder of Method Media Intelligence, which he founded with Shailin Dhar, who has been on the show several times to discuss his investigations into the world of ad fraud. I wanted to have his partner Praneet on the show to get his perspective on ad fraud and how to clean up the advertising ecosystem.

One advance in dynamic advertising that we discussed is header bidding, and an open source library called PrebidJS.

When an ad-supported website gets delivered to your web browser, the HTML begins to load and the JavaScript on the page begins to execute. Some of that JavaScript is calling out to advertising networks looking for the highest bidder. Until the page receives a callback for what to put in the ad slots on the page, the page will not finish loading. Sites that do not manage their ad requests appropriately suffer performance issues.

Header bidding is a technique to wrap all of the requests to different advertising exchanges in a single serialized blob of code at the top of the page.

", + "Episodes Title": "Advertiser Bidding with Praneet Sharma", + "Episodes Uid": "SED6682380186", + "Episodes Audio File": "1e67037cf9412aa6a2a70540ee28ea20.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 294, + "Episodes ID": "1222e83a-e329-11ea-91a2-f7e90bf17194", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/adfraud_edited.mp3", + "Episodes Pubdate Date": "2016-10-28", + "Episodes Summary": "

Advertising fraud takes billions of dollars out of the economy every year. We don’t know exactly how much money is being lost, because we don’t know what percentage of Internet users are bots. Are You A Human is a company designed to solve that exact problem, and provide a service for verifying whether a user is real or automated.

Ben Trenda is the CEO of Are You A Human. In this episode, we discuss some of the ways that bots pose as humans–clicking on ads, pretending to read ads, and defrauding marketers and publishers. We also talk about how Are You A Human combats this.

This episode is part of a series of episodes about advertising fraud. If you know anything about the area, send me an email: jeff@softwareengineeringdaily.com

", + "Episodes Title": "Ad Fraud with Ben Trenda", + "Episodes Uid": "SED5896461299", + "Episodes Audio File": "dad1b107508067b78537595cd504c2ac.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2id", + "Episodes ID": "05a9a01c-e329-11ea-91a2-474e798ccf87", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Equity_Compensation.mp3", + "Episodes Pubdate Date": "2017-03-02", + "Episodes Summary": "

When an engineer is offered a job a tech company, their compensation is often partly in cash and partly in equity–shares of the company. How should an engineer evaluate that offer? How should they negotiate? In the world of equity compensation, costly and avoidable mistakes are routine, and this hurts both companies and employees.

Josh Levy was on Software Engineering Daily previously to talk about the Amazon Web Services open guide, which was one of the most popular episodes we have ever had. In this episode, Josh and I are joined by Joe Wallin, a lawyer who has been involved in startups for many years.

Josh and Joe are the authors of the The Open Guide to Equity Compensation, which is a resource designed to clear up the confusion around stock, options, and fundraising. It’s a tremendously useful and concise overview of what an engineer or founder needs to know when it comes to equity financing.

", + "Episodes Title": "Equity Compensation with Joshua Levy and Joe Wallin", + "Episodes Uid": "SED7603519760", + "Episodes Audio File": "b67baa602c3c10dfbe784ef80d4ea35b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 317, + "Episodes ID": "f69eaa54-e328-11ea-91a2-9be1faa12310", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ClaudeShannon.mp3", + "Episodes Pubdate Date": "2017-09-04", + "Episodes Summary": "

We write code in a language that looks like English. Whether it is JavaScript, Fortran, or assembly language, that code is an abstraction on top of layers of intermediate languages, binary, transistors, and physics. 100 years ago, this would have seemed like magic.

Most of us know about Alan Turing, who described the vision of a multipurpose computer with the concept of the Turing machine. Less well known is the scientist Claude Shannon, who laid the groundwork of information theory. With information theory, we can compress data and communicate it efficiently.

Jimmy Soni and Rob Goodman are the authors of “A Mind at Play,” a biography of Claude Shannon. Claude’s unique insights about information were made possible by his willingness to involve himself in lots of different areas–science, art, juggling, warfare. This interview gives insights for how we can think of new ideas by synthesizing disparate subjects.

There are 600 episodes of Software Engineering Daily, and it can be hard to find the shows that will interest you. If you have an iPhone and you listen to a lot of Software Engineering Daily, check out the Software Engineering Daily mobile app in the iOS App Store. Every episode can be accessed through the app, and we give you recommendations based on the ones you have already heard.

", + "Episodes Title": "Information Theory with Jimmy Soni and Rob Goodman", + "Episodes Uid": "SED2504356393", + "Episodes Audio File": "4274cd4cc44c358859f21d99eb49e999.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xg", + "Episodes ID": "ed2e98a8-e328-11ea-91a2-e7ebc7332dfa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_15_FacebookPHP.mp3", + "Episodes Pubdate Date": "2019-07-15", + "Episodes Summary": "

Facebook was built using PHP, a programming language that was used widely in the late 90s and early 2000s. PHP allows developers to get web applications built quickly and easily, although PHP has a reputation for being difficult to scale. 

In the early days of Facebook, the company was scaling rapidly on every dimension. 

New users were piling into Facebook. Existing users were increasing their interactions and developing new patterns of usage. The Facebook application was rolling out new features quickly, adding them into the Facebook PHP codebase.

A common pattern for scaling a large software application is to use a microservices architecture, breaking up the monolithic application into small services which can scale independently. For many applications, this pattern works well. But for some applications, microservices makes less sense.

Microsoft Excel is one example. In Excel, a user is making updates to a complex data model using formulas, functions, and other in-app tools that need to be fast, performant, and integrated. The user needs to have a sense that the Excel data model will update quickly in response to changes. 

A software team working on a spreadsheet product such as Excel might prefer to keep all the application logic in a monolithic application. 

A monolith can centralize logic and make it easier to reason about. A monolith can reduce the number of network hops, cutting down on distributed systems problems. Testing and deploying a monolithic application can be less complex than doing so in a distributed, microservices system.

Facebook chose to scale its PHP monolith rather than breaking it up into distributed microservices. Scaling PHP allowed Facebook to continue moving fast without going through a painful refactoring that would have slowed down the entire company. 

The first effort to scale PHP involved transpiling the entire PHP application into C++. This C++ version of Facebook ran faster and with a lower memory footprint. But C++ required ahead-of-time compilation: the PHP codebase had to be converted to C++ in one synchronous step.

The Hip Hop Virtual Machine (HHVM) was started to allow the Facebook PHP monolith to run on the V8 JavaScript virtual machine. 

The advantage of running PHP on V8 was that it allowed Facebook to transpile PHP to JavaScript, an interpreted language that fit better with Facebook’s dynamic application build path. HHVM also allows Facebook to take advantage of the rapidly improving JavaScript runtime environment.

Keith Adams was an engineer at Facebook for six years, where he helped develop infrastructure to scale PHP effectively. Keith is now the chief architect at Slack, which is also a scaled PHP application. Keith returns to Software Engineering Daily to discuss why and how Facebook scaled PHP.

", + "Episodes Title": "Facebook PHP with Keith Adams", + "Episodes Uid": "SED3572397863", + "Episodes Audio File": "9a970cac9da2c27cb5964f242a097559.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3mc", + "Episodes ID": "f3b56260-e328-11ea-91a2-637c11976fe5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_30_ShapeshiftErikVoorhees.mp3", + "Episodes Pubdate Date": "2018-03-30", + "Episodes Summary": "

“The Federal Reserve System is fraudulent. Whatever its stated purpose, its effective purpose is to create a mechanism of deficit spending by politicians, through the insidious invisible taxation of monetary debasement (aka inflation).”

These are the words of Erik Voorhees, the CEO of crypto financial exchange ShapeShift. Long before he started ShapeShift, Erik was opposed to some of the core principles of the global financial system, in which he sees the US dollar as a means of control. As an early adopter of Bitcoin, he saw a way to make financial transactions without using fiat currency.

Erik’s company ShapeShift allows users to convert different digital currencies between each other. Because it only makes exchanges of currencies and does not hold much currency at any time, ShapeShift is resilient to hacking.

In this episode, Erik and I discussed his economic philosophy, and how that informs his affinity for cryptocurrencies. Erik also describes the architecture of ShapeShift, and gives some advice for how to think about building businesses around cryptocurrencies. ShapeShift has had a few near-death experiences, like any startup, and there is a useful story in this episode about how to survive and recover from a serious business setback.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "ShapeShift with Erik Voorhees", + "Episodes Uid": "SED2691515688", + "Episodes Audio File": "fa29c166c052536288e0f52fca1e0073.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "37s", + "Episodes ID": "f5a74e9e-e328-11ea-91a2-9753baaf7975", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/BigQuery.mp3", + "Episodes Pubdate Date": "2017-11-13", + "Episodes Summary": "

Large-scale data analysis was pioneered by Google, with the MapReduce paper. Since then, Google’s approach to analytics has evolved rapidly, marked by papers such as Dataflow and Dremel.

Dremel combined a column-oriented, distributed file system with a novel way of processing queries. A single Dremel query is distributed into a tree of servers, starting with the root server, splitting into the intermediate servers, and ending with the leaf servers talking to the file system. Once the data is pulled from the file system into the leaves, the data propagates back to the root server, and is shuffled along the way so that the root server receives a sorted response.

When Google started turning its internal services into customer-facing cloud products, the effort to productize Dremel began, and BigQuery was born. Jordan Tigani is an engineering lead who works on BigQuery, and he joins the show to discuss the evolution of the data warehouse.

Large scale distributed queries still can take a long time–but queries get faster every year. Queries that required a nightly Hadoop job 10 years ago can be viewed in a frequently updated user-facing dashboard. Power users of BigQuery talk about the speed and the query interface as being two of its most valuable differentiating features. As the job of a large scale data analyst becomes less technically intensive, tools like BigQuery will continue to rise in popularity.

We have done some great shows about Google papers like Spanner, Dremel, and Dataflow. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Shout out to today’s featured contributor Shreyans Sheth. Shreyans has worked on the Software Engineering Daily search API, and has also helped us understand open source best practices, which we are still learning. Thanks again Shreyans for your work.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "BigQuery with Jordan Tigani", + "Episodes Uid": "SED4878151358", + "Episodes Audio File": "f20367e956b2ef48652bce48612697e2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6h4", + "Episodes ID": "eb669d72-e328-11ea-91a2-c3e573b2f484", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_24_PrestoandParquet.mp3", + "Episodes Pubdate Date": "2019-11-28", + "Episodes Summary": "

Originally published May 24, 2018

When a user takes a ride on Uber, the app on the user’s phone is communicating with Uber’s backend infrastructure, which is writing to a database that maintains the state of that user’s activity. This database is known as a transactional database or “OLTP” (online transaction processing). Every active user and driver and UberEATS restaurant is writing data to the transactional data store.

Periodically, that data is copied from the transactional data system to a different data storage system, where that data can be queried for large-scale data analysis. For example, if a data scientist at Uber wants to get the average amount of miles that a given user rode in February, that data scientist would issue a query to the analytical data cluster.

Uber uses the Hadoop distributed file system (HDFS) to store analytical data. On this file system, Uber has a version history of all of the company’s useful historical data. Trip history, rider activity, driver activity–every data point that is in the transactional database–but in a file format that is easier to query for large scale processing. This file format is known as Parquet.

Data scientists, machine learning engineers, and real-time application developers all depend on the massive quantities of data that are stored in these Parquet files on Uber’s HDFS cluster. To simplify the access of that data by many different clients, Uber uses Presto, an analytical query engine originally built at Facebook.

Presto translates SQL queries into whatever query language is necessary to access the underlying storage medium–whether that storage system is an ElasticSearch cluster, a set of Parquet files, or a relational database. Presto is useful because it simplifies the relationship between data engineers and the application developers who are building on top of the data engineering infrastructure.

In today’s show, Zhenxiao Luo joins to give an end-to-end description of Uber’s data infrastructure–from the ingest point of the OLTP database to the OLAP data storage system on HDFS, to the wide range of data systems and applications that run on top of that OLAP data.

", + "Episodes Title": "Uber’s Data Platform with Zhenxiao Luo Holiday Repeat", + "Episodes Uid": "SED4884788935", + "Episodes Audio File": "dff1f352ae790c01fe14caee18234c9b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4g8", + "Episodes ID": "f164c708-e328-11ea-91a2-cbde4a6fd294", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_12_NetflixObservabilitywithKevinLew.mp3", + "Episodes Pubdate Date": "2018-09-12", + "Episodes Summary": "

Netflix users stream terabytes of data from the cloud to their devices every day. During a high bandwidth, long-lived connection, a lot can go wrong. Networks can drop packets, machines can run out of memory, and the Netflix app on a user’s device can have a bug. All of these events can result in a bad user experience.

Other errors can occur that do not disrupt the user experience. Netflix runs thousands of machine learning jobs, logging servers, and other pieces of internal infrastructure. Customer service dashboards, CI/CD pipelines, and AB testing frameworks are all software built by Netflix–and when an error occurs in any of these places, engineers need to be able to diagnose and debug that error.

Observability is the practice of using logs, monitoring, metrics, and distributed tracing to understand how a system is working. Kevin Lew is a senior software engineer at Netflix with the Edge Insights team. He joins the show to talk about adding observability across the microservices deployed at Netflix. We also talk about how to manage high volumes of logging data effectively using stream processing.

", + "Episodes Title": "Netflix Observability with Kevin Lew", + "Episodes Uid": "SED5294118141", + "Episodes Audio File": "090ec307739659ee60f20e473b3e1d18.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48q", + "Episodes ID": "f1d3ded6-e328-11ea-91a2-8f8b6012f692", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_07_OpenSourceChadFowler.mp3", + "Episodes Pubdate Date": "2018-08-07", + "Episodes Summary": "

Chad Fowler was the CTO of Wunderlist prior to its acquisition by Microsoft. Since the acquisition, Chad has become the general manager of developer advocacy at Microsoft. He also works as a venture capitalist at BlueYard Capital, an early stage investment firm.

I’ve had a lot of fun talking to Chad, because he can move seamlessly between talking about disparate subjects like cloud computing, investing, cryptocurrencies, and music composition. And he has novel things to say about all of them!

When Chad joined Wunderlist, he helped start a large refactoring of the software architecture. He then helped the company navigate to the successful Microsoft acquisition. We started off the conversation with the story of this rearchitecture, and how he sees the current opportunities in front of Microsoft. Chad gives his perspective on Kubernetes, functions-as-a-service, and how developer tooling might evolve in the near future.

After talking about near-term developer tooling, we talked about the distant future: bug bounty marketplaces on the blockchain; using Github repositories to train machine learning models about how to write code; the comparison between music collaboration and software collaboration. This was a wide array of topics, but Chad was equipped to discuss all of them–since he works at Microsoft, makes large investments in the future, and studied music when he was in school.

", + "Episodes Title": "Future Architecture with Chad Fowler", + "Episodes Uid": "SED6543262397", + "Episodes Audio File": "f2440ef5432fc22844cc1f405f6402af.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2rk", + "Episodes ID": "fa62686a-e328-11ea-91a2-0b7f45d96b84", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/cosmosdb_edited.mp3", + "Episodes Pubdate Date": "2017-06-01", + "Episodes Summary": "

Different databases have different access patterns. Key-value, document, graph, and columnar databases are useful under different circumstances.

For example, if you are a bank, and you have a database of customers and the transactions they have performed, the ideal access pattern for aggregating the total amount of all transactions might be a columnar store. If the transaction amounts are all in one column, it helps to have all of the columnar entries close together on disk.

But if you want to look at your bank as a social network, and you want to be able to map how money flows between the different people who use your bank, you might want to map your data as a graph database. That would make it easier to query for the connections across the different users in the bank.

CosmosDB is a database from Microsoft that allows for multiple data models and multiple well-defined consistency models. Today’s guest Andy Hoh is a product manager at Azure CosmosDB and he joins the show to describe the product.

Microsoft unveiled CosmosDB at Build, their annual developer conference, which is where I performed this interview. It was a pleasure hanging out at Build in the podcast booths they set up, so thanks to Microsoft for inviting me.

", + "Episodes Title": "CosmosDB with Andrew Hoh", + "Episodes Uid": "SED8553477243", + "Episodes Audio File": "0ee0239049b1a9a6fa82eda7e9da9bb8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3bc", + "Episodes ID": "f530b2ac-e328-11ea-91a2-679e4538bc4a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ProtocolBuffers.mp3", + "Episodes Pubdate Date": "2017-12-18", + "Episodes Summary": "

When engineers are writing code, they are manipulating objects. You might have a user object represented on your computer, and that user object has several different fields—a name, a gender, and an age.

When you want to send that object across the network to a different computer, the object needs to be turned into a sequence of 1s and 0s that will travel efficiently across the network. This is known as “serialization.”

As the user object sits on your computer, it is represented in 1s and 0s. You could just send that same representation over the wire. But we use efficient serialization to send it over the network in a more compact format. We also have to make sure that when we send that object to another service, the other service knows how to deserialize it, and turn it back into a format that we can operate on at the application level.

Protocol buffers are a serialization protocol that originated at Google. Protocol buffers created a standardized interface for efficiently passing data between services. When Kenton Varda worked at Google, he was the tech lead for protocol buffers, and he joins the show to explain how protobufs work—and a newer serialization protocol that Kenton led: Cap’n Proto.

You can expect to walk away from this episode with an understanding of how serialization protocols work, and the design tradeoffs you can make when creating a serialization protocol.

We also touched on a startup that Kenton founded, called Sandstorm, and how he eventually found himself at Cloudflare, where he works on Cloudflare workers. With these topics, we did not go as deep as I would have liked, and I look forward to having Kenton back on in the near future.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Protocol Buffers with Kenton Varda", + "Episodes Uid": "SED8937552792", + "Episodes Audio File": "be79ea4020e4d64b9b1ce04b26d35b76.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7z", + "Episodes ID": "3737f8f4-e329-11ea-91a2-ef65f4919451", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/faisal_btc_fixed.mp3", + "Episodes Pubdate Date": "2015-08-11", + "Episodes Summary": "

Faisal Khan is a banking, payments, and fintech consultant with a background in electrical engineering.

", + "Episodes Title": "Payments Engineering with Faisal Khan", + "Episodes Uid": "SED1859063433", + "Episodes Audio File": "f22c62be81ef61c6316b735a39e75eb7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5r6", + "Episodes ID": "edfaf998-e328-11ea-91a2-efded3a0b774", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_22_Monoliths.mp3", + "Episodes Pubdate Date": "2019-05-22", + "Episodes Summary": "

Google’s codebase is managed in a single monolithic repository. An engineer at Google can explore almost any area of the codebase within the entire company. In order to enable this, Google has built tooling to support the monolithic repo, including a virtual file system and a set of build tools.

A monolithic repository is not to be confused with a monolithic deployment. Google’s infrastructure consists of thousands of small services interacting over a network, and scaling individually. But all of the code for each of these different independent modules is in the same version control system.

Ciera Jaspan is a staff software engineer at Google working on developer infrastructure. She worked on an internal research project within Google to find out how engineers felt about the monolithic repository system and how it compared to a large number of small repositories.

Ciera joins the show to discuss repository management, internal tooling, and Google’s approach to researching developer productivity within the company.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Monolithic Repositories with Ciera Jaspan", + "Episodes Uid": "SED7398551638", + "Episodes Audio File": "022d4f970736b55cc311718c9c4fcd1f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4ig", + "Episodes ID": "f14e6ce2-e328-11ea-91a2-03f4af20e5f0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_20_KubernetesDistributions.mp3", + "Episodes Pubdate Date": "2018-09-19", + "Episodes Summary": "

Kubernetes is an open source container management system. Kubernetes is sometimes described as “the Linux of distributed systems” and this description makes sense: the large numbers of users and contributors in the Kubernetes community is comparable to the volume of Linux adopters in its early days.

There are many different distributions of Linux: Ubuntu, Red Hat, Chromium OS. These different operating system distributions were created to fulfill different needs. Linux is used for Raspberry Pis, Android phones, and enterprise workstations. These different use cases require different configurations of an operating system.

Similarly, there are different distributions of Kubernetes because there are different types of distributed systems. The internal infrastructure of a cloud provider might use one type of Kubernetes to serve users running application containers. A network of smart security cameras might be networked together with a different distribution of Kubernetes.

Brian Gracely and Michael Hausenblas join the show today to discuss Kubernetes distributions. Brian and Michael work at Red Hat, which helps maintain the Origin Community Distribution of Kubernetes, which Red Hat OpenShift runs on. OpenShift is a platform as a service that enterprises use to deploy and manage their applications. Full disclosure: Red Hat is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Kubernetes Distributions with Brian Gracely and Michael Hausenblas", + "Episodes Uid": "SED4972005592", + "Episodes Audio File": "70034a254c94258a5965094766b2b36c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ir", + "Episodes ID": "f43c3c2c-e328-11ea-91a2-1fdc608949fb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_21_MikeDaLessio.mp3", + "Episodes Pubdate Date": "2018-02-21", + "Episodes Summary": "

Earlier this year we did several shows about Cloud Foundry, followed by several shows about Kubernetes. Both of these projects allow you to build scalable, multi-node applications–but they serve different types of users.

Cloud Foundry encompasses a larger scope of the application experience than Kubernetes. Kubernetes is lower level, and is actually being used within newer versions of Cloud Foundry to give Cloud Foundry users access to the Kubernetes abstractions.

Recording those shows gave me a wide understanding of how infrastructure is managed and how it has evolved. Today’s episode provides more context on Cloud Foundry–how the project got started, how people use it, and where Cloud Foundry is going. Today’s guest Mike Dalessio is a VP of engineering on Pivotal Cloud Foundry, and we had a great time talking about his work. Engineering leadership is a fine art, and conversations with engineering leaders are consistently interesting–this was no exception.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cloud Foundry Overview with Mike Dalessio", + "Episodes Uid": "SED4342182894", + "Episodes Audio File": "3bb39f55ca1e9ac170e6d704c3e95a8f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2v0", + "Episodes ID": "f763dacc-e328-11ea-91a2-3f4a358701ba", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SoupsPresentation.mp3", + "Episodes Pubdate Date": "2017-07-09", + "Episodes Summary": "

A cryptocurrency exchange faces a uniquely difficult fraud problem. A hacker who steals my credentials can initiate a transfer of all my bitcoin to another wallet, and it is a non-reversible, non-identifiable payment. So it is really important to prevent those kinds of fraudulent transactions.

At the third Software Engineering Daily Meetup, Coinbase director of data science Soups Ranjan explained how Coinbase stays ahead of fraudsters, and he describes some of the cutting-edge social engineering attacks that are being used to try to steal cryptocurrency–including cell phone takeover attacks.

Next week, we will be airing three shows I did on-site at Coinbase–interviews with engineers from three different teams. Check out those shows for a deep dive into cryptocurrency uses, fraud, and infrastructure. Coinbase is an exciting company, and it was a lot of fun getting a panorama for how several parts of the organization function.

The next Meetup will be in New York. We don’t know when it will be yet, but sign up to follow us at softwareengineeringdaily.com/meetup.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Fighting Fraud at Coinbase with Soups Ranjan", + "Episodes Uid": "SED1837236375", + "Episodes Audio File": "16ba6b5a8a1d3cbee7eb456ea39c3e2b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2pk", + "Episodes ID": "fbfaf430-e328-11ea-91a2-07ce8c9096e1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ClarifaiCNNs.mp3", + "Episodes Pubdate Date": "2017-05-10", + "Episodes Summary": "

Convolutional neural networks are a machine learning tool that uses layers of convolution and pooling to process and classify inputs. CNNs are useful for identifying objects in images and video. In this episode, we focus on the application of convolutional neural networks to image and video recognition and classification.

Matt Zeiler is the CEO of Clarifai, an API for image and video recognition. Matt takes us through the basics of a convolutional neural network–you don’t need any background in machine learning to understand the content of the episode. He also discusses the subjective aspects of image and video recognition, and some of the tactics Clarifai has explored. This is far from a solved problem.

Matt also discusses the infrastructure of Clarifai–how they use Kubernetes, how models are deployed, and how models are updated.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view the transcript for this episode.

", + "Episodes Title": "Convolutional Neural Networks with Matt Zeiler", + "Episodes Uid": "SED5224933512", + "Episodes Audio File": "7bd47197281e25fa22c958bfd7298bb7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4l8", + "Episodes ID": "f133a178-e328-11ea-91a2-3ff5c24d1207", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_27_AndroidThings.mp3", + "Episodes Pubdate Date": "2018-09-27", + "Episodes Summary": "

Internet of Things is a concept that describes lots of devices that you interact with regularly being connected to the Internet and networked together.

Technologists have been dreaming of the world of IoT for many years, where our connected refrigerator can detect that we are out of food, and automatically order more food. Or our connected bathroom can scan us for diseases and recommend treatment.

The bright future of IoT is slowly coming together. Hardware prototyping is getting cheaper. Voice interfaces and machine learning are creating new mediums for communicating with devices. Platforms like Kickstarter are allowing developers to validate the market for their products and raise the necessary capital to build their product.

Android Things is a developer platform for IoT applications based on the Android Operating system. Android Things consists of hardware devices and software tools that reduce common IoT problems such as software updates and security patches. Wayne Piekarski is a staff developer advocate at Google, and he joins the show to talk about the state of IoT and why Google built Android Things.

", + "Episodes Title": "Android Things with Wayne Piekarski", + "Episodes Uid": "SED9559092532", + "Episodes Audio File": "dee323c52ecabf700834fabe071fda70.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4nh", + "Episodes ID": "f11dcfba-e328-11ea-91a2-6788225d5dc4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_04_DatabasePerformanceandOptimization.mp3", + "Episodes Pubdate Date": "2018-10-04", + "Episodes Summary": "

When a database gets large, it can start to perform poorly. This can manifest in slow query speed. You can speed up a query by defining an index, which is a data structure that allows for faster access to the data that is being indexed. As a consequence, whenever you update the database, you will now need to update the index with that new piece of data.

The more you index your data, the faster the access time. In order to have more indexes you must pay a write penalty in order to maintain consistency around that data, since the indexes need to be updated with each new entry. This illustrates one simple tradeoff that a developer can make within a database deployment.

Why are there so many different databases in the world? Why do we need SQL databases like Postgres, document databases like MongoDB, key/value systems like Cassandra, and search systems like Elasticsearch? Because each of these each system optimizes for different sets of tradeoffs. Tradeoffs can affect the speed of a read, the speed of a write, the user experience, the consistency of data, and the cost of running the database.

Andrew Davidson is the lead product manager of MongoDB Atlas. Andrew joins the show to talk about how database performance can degrade when a database gets large, and how to measure and optimize performance of a critical database.

Andrew explores the range of distributed systems cases–from a single node database to a multi-geographic distribution of nodes around the world, and describes how the configuration of a database in the cloud can help or hurt the application that the database is serving.
\nFull disclosure: MongoDB is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Database Performance and Optimization with Andrew Davidson", + "Episodes Uid": "SED6030182673", + "Episodes Audio File": "a771373d3ff4e399196ec3779096c0a5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ox", + "Episodes ID": "ee26f656-e328-11ea-91a2-8b84e3c3c4d8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_09_DataSystems.mp3", + "Episodes Pubdate Date": "2019-05-09", + "Episodes Summary": "

Relational data systems have evolved from single node instances to complex distributed systems.

Almost any database can be accessed through a SQL statement, but the guarantees of these databases can vary in terms of consistency, availability, latency, durability, and financial cost. Relational database systems that explore these different sets of tradeoffs are sometimes categorized as “NewSQL”.

There are also a wide variety of data systems that are not categorized as databases. Kafka is a distributed queue. HDFS is a distributed file system. Spark provides a distributed in-memory working set to process data. Cloud providers offer hosted bucket storage for your data lake and fast processing in the form of a data warehouse.

Sunil Kamath is a principal PM with Microsoft. Sunil has worked on database systems for two decades, and he joins the show to give his perspective on the current data world and his predictions for how data platforms will become easier to use. Sunil is optimistic about the use of virtual data for unifying the access of data for a variety of operational use cases.

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Virtual Data with Sunil Kamath", + "Episodes Uid": "SED9426587975", + "Episodes Audio File": "bd85c693b98ae7b361ebb45c57632ee3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3fx", + "Episodes ID": "f492558a-e328-11ea-91a2-53055f824fc6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_29_DeepLearningHardware.mp3", + "Episodes Pubdate Date": "2018-01-29", + "Episodes Summary": "

Training a deep learning model involves operations over tensors. A tensor is a multi-dimensional array of numbers. For several years, GPUs were used for these linear algebra calculations. That’s because graphics chips are built to efficiently process matrix operations.

Tensor processing consists of linear algebra operations that are similar in some ways to graphics processing–but not identical. Deep learning workloads do not run as efficiently on these conventional GPUs as they would on specialized chips, built specifically for deep learning.

In order to train deep learning models faster, new hardware needs to be designed with tensor processing in mind.

Xin Wang is a data scientist with the artificial intelligence products group at Intel. He joins today’s show to discuss deep learning hardware and Flexpoint, a way to improve the efficiency of space that tensors take up on a chip. Xin presented his work at NIPS, the Neural Information Processing Systems conference, and we talked about what he saw at NIPs that excited him. Full disclosure: Intel, where Xin works, is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Deep Learning Hardware with Xin Wang", + "Episodes Uid": "SED8275742215", + "Episodes Audio File": "1c025d3d6f4ed897e2183e33d1538046.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5do", + "Episodes ID": "ef41a73e-e328-11ea-91a2-63f13ddb469b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_25_EdgeComputingLF.mp3", + "Episodes Pubdate Date": "2019-02-25", + "Episodes Summary": "

Edge computing refers to computation involving drones, connected cars, smart factories, or IoT sensors. Any software deployment that is not a large centralized server installation could qualify as an edge device–even a smartphone.

Today, much of our heavy computation takes place in the cloud–a set of remote data centers some distance away from our client devices. For many use cases, this works fine. But there are a growing number of use cases with lower latency and higher bandwidth requirements at the edge.

A simple example is video. Let’s say you want to record a video stream, and detect people in that video stream in real time. Based on who those people in the video stream are, you want to do different things–maybe you want to send them a text message, or report to the police that a dangerous person has entered the premises. This video stream could be captured by a drone, or by a smart car, or by a video camera mounted somewhere.

Where is the video stream getting stored? Where is the machine learning model running? How do you deploy new machine learning models to the operating system with the machine learning model? This is a simple example, and there are many open questions as to how to best solve such a problem.

With the increased resource constraints at the edge, there is a need for new hardware and software to power these edge applications. This led to the creation of LF Edge, a new open source group under the Linux Foundation. The goal of LF Edge is to build an open source framework for the edge.

Arpit Joshipura is the general manager of networking, orchestration, edge computing, and IoT with the Linux Foundation. He joins the show to describe the state of edge computation, and the mission of LF Edge.

This episode was exciting for several reasons. After seeing the rise of Kubernetes for container orchestration, we know that a popular open source technology that solves a widespread problem can have dramatic influence on the software world. And when multiple large companies get involved in that open source project, it can gain traction quite quickly.

Edge computing has a large set of unanswered questions, but telecom providers like AT&T and large infrastructure companies like Dell EMC are getting heavily involved with the Linux Foundation Edge group. This represents a significant expansion of the open source model, and a suggestion of further investment into open source projects in the near future.

", + "Episodes Title": "Edge Computing Open Source with Arpit Joshipura", + "Episodes Uid": "SED8812017407", + "Episodes Audio File": "d29e307a44ad605392f7f5b715ba2a11.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 594, + "Episodes ID": "efb880fc-e328-11ea-91a2-63389f5f408c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_21_Cortex.mp3", + "Episodes Pubdate Date": "2019-01-21", + "Episodes Summary": "

Prometheus is an open source monitoring system and time series database. Prometheus includes a multi-dimensional data model, a query language called PromQL, and a pull model for gathering metrics from your different services. Prometheus is widely used by large distributed systems deployments such as Kubernetes and Cloud Foundry.

Prometheus gathers metrics from your services by periodically scraping those services. Those metrics get gathered, compressed, and stored onto disk for querying. But Prometheus is designed to store all of its records on one host in one set of files–which limits the scalability and availability of those metrics.

Cortex is an open source project built to scale Prometheus. Cortex effectively shards Prometheus by parallelizing the “ingestion” and storage of Prometheus metrics. Cortex can take metrics from multiple Prometheus instances and store them across a distributed NoSQL database like DynamoDB, BigTable, or Cassandra.

Bryan Boreham is an engineer at Weaveworks, where he works on deployment, observability, and monitoring tools for containers and microservices. He wrote much of the code for Cortex, and we met up at KubeCon North America to talk about the motivation for creating Cortex, the broader landscape of Kubernetes monitoring, and other approaches to scaling Prometheus.

", + "Episodes Title": "Prometheus Scalability with Bryan Boreham", + "Episodes Uid": "SED8972183399", + "Episodes Audio File": "8ce55db958ec1d0302f8d43fe2d839c1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "64d", + "Episodes ID": "ec99de3e-e328-11ea-91a2-8f6ec0472472", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_28_FacebookProcessKentBeck.mp3", + "Episodes Pubdate Date": "2019-08-28", + "Episodes Summary": "

Kent Beck is a legendary figure in the world of software engineering. 

Kent was an early advocate of Test-Driven Development (TDD), and popularized the idea of writing unit tests before writing code that would satisfy those unit tests. A unit test isolates and tests a small piece of functionality within a large piece of software. Practitioners of Test-Driven Development write tens or hundreds of tests in order to cover a large variety of cases that could potentially occur within their software.

When Kent Beck joined Facebook in 2011, he was 50 years old and thought he had seen everything in the software industry. During Facebook Boot Camp, Kent started to realize that Facebook was very different than any other company he had seen. Facebook Boot Camp is the six-week onboarding process that every new hire learns about the software practices of the company.

After graduating Facebook Boot Camp, Kent began to explore Facebook’s codebase and culture. He found himself rethinking many of the tenets of software engineering that he had previously thought were immutable.

Kent joins the show to discuss his time at Facebook, and how the company’s approach to building and scaling products thoroughly reshaped his beliefs about software engineering.

", + "Episodes Title": "Facebook Engineering Process with Kent Beck", + "Episodes Uid": "SED3387920276", + "Episodes Audio File": "234b2bea859a97b80b8b800aa648fc9e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4yp", + "Episodes ID": "f076b4be-e328-11ea-91a2-9f3330941e84", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Libratus.mp3", + "Episodes Pubdate Date": "2018-11-21", + "Episodes Summary": "

Originally posted on May 12, 2015.

Humans have now been defeated by computers at heads up no-limit holdem poker.

Some people thought this wouldn’t be possible. Sure, we can teach a computer to beat a human at Go or Chess. Those games have a smaller decision space. There is no hidden information. There is no bluffing. Poker must be different! It is too human to be automated.

The game space of poker is different than that of Go. It has 10^160 different situations–which is more than the number of atoms in the universe. And the game space keeps getting bigger as the stack sizes of the two competitors gets bigger.

But it is still possible for a computer to beat a human at calculating game theory optimal decisions–if you approach the problem correctly.

Libratus was developed by CMU professor Tuomas Sandholm, along with my guest today Noam Brown. The Libratus team taught their AI the rules of poker, they gave it a reward function (to win as much money as possible), and they told it to optimize that reward function. Then they had Libratus train itself with simulations.

After enough training, Libratus was ready to crush human competitors, which it did in hilarious, entertaining fashion. There is a video from Engadget on YouTube about the AI competing against professional humans.

In this episode, Noam Brown explains how they built Libratus, what it means for poker players, and what the implications are for humanity–if we can automate poker, what can’t we automate?

Stay tuned at the end of this episode for the Indeed Prime tip on hiring developers.

", + "Episodes Title": "Poker Artificial Intelligence with Noam Brown Holiday Repeat", + "Episodes Uid": "SED4832918232", + "Episodes Audio File": "31bce463d564cd5472dee648fec32d4f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2sf", + "Episodes ID": "f9bda762-e328-11ea-91a2-f714e7ae59e2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Fission.mp3", + "Episodes Pubdate Date": "2017-06-12", + "Episodes Summary": "

Kubernetes is an orchestration system for managing containers. Since it was open sourced by Google, Kubernetes has created a wave of innovation in the infrastructure technology space.

Another recent innovation has been the “serverless” execution tools–such as AWS Lambda and Google Cloud Functions. Serverless execution, otherwise known as functions-as-a-service, allows a developer to execute code against cloud servers without specifying which cloud servers they are executing on.

Serverless execution is a cheap, flexible resource that any large company wants to have access to. But AWS Lambda and the other popular serverless tools are closed source. This led Soam Vasani to work on Fission, a serverless executor that sits on top of Kubernetes.

If you have not heard about either Kubernetes or Serverless, you can check out our previous episodes about either topic. If you are familiar with the two topics, I think you’ll enjoy this episode, in which Soam explains the motivation for serverless on Kubernetes, and the architecture of Fission.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless on Kubernetes with Soam Vasani", + "Episodes Uid": "SED1750560411", + "Episodes Audio File": "17bcb84e89ec6edc8a9959d1c79c5bbe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3wk", + "Episodes ID": "f2e17f68-e328-11ea-91a2-2fbd92057056", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_29_PiHole.mp3", + "Episodes Pubdate Date": "2018-05-29", + "Episodes Summary": "

Ad blockers in the browser protect us from the most annoying marketing messages that the Internet tries to serve to us. But we still pay a price for these ads. We pay the bandwidth costs of requesting these pages. Our browsers are slowed down by these extra requests.

Pi Hole is a hardware based ad blocker. Pi Hole acts as a DNS server for all of the traffic that makes its way onto your network. Pi Hole has a blacklist of all the URLs to block–including tracking systems and ad networks. Pi Hole stops these URLs from communicating with all the devices on your network–including your cell phone.

Jacob Salmela is the developer of Pi Hole, which he describes as a black hole for advertiser traffic. In this episode, we explain how traditional ad blocking in the browser works, and how things are improved with a piece of dedicated hardware doing the ad blocking. It was also a useful review of the relationship between URLs, IP addresses, your home network, and the broader Internet.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Pi Hole: Ad Blocker Hardware with Jacob Salmela", + "Episodes Uid": "SED9208307486", + "Episodes Audio File": "ee9c3adb46f61d044049ad4b313e2d87.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3gz", + "Episodes ID": "f4694ae6-e328-11ea-91a2-170d0ce35397", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_08_OutSystems.mp3", + "Episodes Pubdate Date": "2018-02-08", + "Episodes Summary": "

Applications need to be ready to scale in response to high-load events. With mobile applications, this can be even more important. People rely on mobile applications such as banking, ride sharing, and GPS.

During Black Friday, a popular ecommerce application could be bombarded by user requests–you might not be able to complete a request to buy an item at the Black Friday discount. If you attend the Superbowl, and then try to catch an Uber after leaving, all the other people around you might be summoning a car at the same time, and the system might not scale.

In order to prepare infrastructure for high volume, mobile development teams often create end-to-end load tests. After recording incoming mobile traffic, that mobile traffic can be replicated and replayed, to measure a backend’s response to the mobile workload.

Paulo Costa and Rodrigo Coutinho are engineers at OutSystems, a company that makes a platform for building low-code mobile applications. In this episode, Paulo and Rodrigo discuss the process of performing end-to-end scalability testing for mobile applications backed by cloud infrastructure.  We talked about the high level process of architecting the load test, and explored the tools used to implement it. Full disclosure: OutSystems is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Load Testing Mobile Applications with Paulo Costa and Rodrigo Coutinho", + "Episodes Uid": "SED2599815469", + "Episodes Audio File": "9e026facdef59127986c64aaf21063bc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jo", + "Episodes ID": "02902720-e329-11ea-91a2-879782b4061f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/brendan-eich_edited.mp3", + "Episodes Pubdate Date": "2017-03-31", + "Episodes Summary": "

Brendan Eich created the first version of JavaScript in 10 days. Since then JavaScript has evolved, and Brendan has watched the growth of the web give rise to new and unexpected use cases.

Today Brendan Eich is still pushing the web forward across the technology stack with his involvement in the WebAssembly specification and the Brave browser.

For all of its progress, JavaScript struggles to run resource-intensive programs like complex video games. With JavaScript falling short on its charge to be the “assembly language for the web” the four major browser vendors started collaborating on the WebAssembly project to allow programming languages a faster, lower level compile target when deploying to the web.

Brendan is the CEO of Brave which aims to provide a faster and safer browsing experience by blocking ads and trackers by default in a new browser. The Brave browser is also helping publishers monetize in interesting new ways while also giving a share of ad revenue to its users.

Caleb Meredith is the host of this show. He previously guest hosted a popular episode on Inferno, a fast, React-like JavaScript framework. As we bring on more guest hosts, please send us feedback. We want to know what every host is doing well, and what we can improve on.

", + "Episodes Title": "WebAssembly with Brendan Eich", + "Episodes Uid": "SED5658528444", + "Episodes Audio File": "5d2af63eb602b276f1983676d9f077a0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "50c", + "Episodes ID": "f0608090-e328-11ea-91a2-4b7de6d42b7c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_30_SlackArchitecture2.mp3", + "Episodes Pubdate Date": "2018-11-28", + "Episodes Summary": "

Slack is a real-time messaging system for work communication. On Slack, chat rooms as big as 100,000 people have productive conversations. This might sound like the same problem solved by social networks like Facebook, where billions of users communicate over a newsfeed. But the engineering constraints of a messaging system are different than that of a social network.

On a newsfeed, the order in which events appear is not chronological. Events can be out of order. You can miss events. When a user posts a message to a social network, there are not strict guarantees around when other people will see that message.

On Slack, messages have strong guarantees around arrival. When I send a message, everyone else who is in the room and connected should quickly receive that message as well. The messages need to be ordered and delivered exactly once. All messages on Slack are persisted.

We have covered the architecture and security model of Slack in previous shows. In today’s show, Keith Adams returns to discuss how messages are processed and broadcast in Slack. The problem of Slack’s messaging system is similar to the distributed systems problem of “atomic broadcast”, in which a single process broadcasts a message which needs to be received by all other processes correctly–or else received by none of them.

In Keith’s last show, he talked through the benefits of building a large system on PHP. He worked on infrastructure at Facebook, which was also a PHP application. It’s worth noting that both Slack and Facebook have scaled a monolithic architecture.

", + "Episodes Title": "Slack Messaging Architecture with Keith Adams", + "Episodes Uid": "SED9370954143", + "Episodes Audio File": "ae37a320d69635023a3af44774c107e1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4sf", + "Episodes ID": "f0d8a49e-e328-11ea-91a2-d7f2bc688eeb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_24_JAMStack.mp3", + "Episodes Pubdate Date": "2018-10-24", + "Episodes Summary": "

Engineers can build applications faster by using tools that abstract away infrastructure. Major cloud providers offer this tooling in the form of functions-as-a-service, as well as managed services such as Google BigQuery or Azure Container Instances.

The term “serverless” refers to these functions-as-a-service and the managed services–because when you use these tools, you are not making calls to specific servers–you are making calls to APIs that abstract away the servers from you, while guaranteeing uptime and reliability. In previous shows we have covered Heroku, Firebase, serverless functions, serverless event driven application development, and a few startups that are built almost entirely on serverless infrastructure.

“Serverless” is a way of describing backend services that are represented by an API. But what about the rest of the application stack that you use to build on top of serverless? You still need to use JavaScript to define the custom code of your application. You still need to use HTML markup to describe the look and feel of your application.

The “JAM Stack” is a way of building applications consisting of JavaScript, APIs, and markup. Phil Hawksworth is the head of developer relations at Netlify, and he joins the podcast to explain how these JAM Stack applications are developed and deployed, and how developers can use the JAM stack to rapidly build new systems.

We recently launched a new podcast: Fintech Daily! Fintech Daily is about payments, cryptocurrencies, trading, and the intersection between finance and technology. You can find it on fintechdaily.co or Apple and Google podcasts. We are looking for other hosts who want to participate. If you are interested in becoming a host, send us an email: host@fintechdaily.co

", + "Episodes Title": "JAM Stack with Phil Hawksworth", + "Episodes Uid": "SED7087835891", + "Episodes Audio File": "f626f529f1aa95ba63869dc439ed9336.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5eh", + "Episodes ID": "ef203806-e328-11ea-91a2-072ac3d8e6d6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_05_EthereumSeanLi.mp3", + "Episodes Pubdate Date": "2019-03-05", + "Episodes Summary": "

Cryptocurrencies enable a large number of applications. Trustless reputation systems, decentralized identity tools, micropayments, non-fungible Internet items, borderless currencies, just to name a few. But cryptocurrencies have not yet impacted daily life, for most of us. Why is that?

One reason is that it is still very hard for developers to build within the cryptocurrency ecosystem. The programming languages, such as Solidity, are not widely used by software engineers. Building and deploying smart contracts is not as easy as deploying a simple Ruby on Rails webapp. The open source tooling is immature, as are the paid developer tools.

Sean Li is the CEO of Fortmatic, a company that is building tools to improve the Ethereum developer experience. Fortmatic simplifies wallet creation, user identity management, security, and money transfer for Ethereum developers.

Before starting Fortmatic, Sean was the founder of Kitematic, a company that made the developer experience of Docker easier. Kitematic was acquired by Docker. Sean is one of the few people with significant experience in both the enterprise container ecosystem and the cryptocurrency ecosystem.

Sean joins the show to discuss his time in the Docker ecosystem, his new company Fortmatic, and his perspective on how to build tools for developers. Someday there will be hundreds of thousands of developers building applications around cryptocurrencies, just like people use cloud computing today.  The road to getting there is unclear, and Sean provides useful insights and predictions for the future.

", + "Episodes Title": "Ethereum Usability with Sean Li", + "Episodes Uid": "SED7602798604", + "Episodes Audio File": "b6bbcd167b0f536a3aa91c29bfd9e3f8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5m0", + "Episodes ID": "ee72777a-e328-11ea-91a2-6fd860c75d62", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_19_ProductswithRyanHoover.mp3", + "Episodes Pubdate Date": "2019-04-19", + "Episodes Summary": "

RECENT UPDATES:

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

FindCollabs Hackathon has ended–winners will probably be announced by the time this episode airs; we will be announcing our next hackathon in a few weeks, so stay tuned

Products are an art form.

As with any art, the world of products includes creators, patrons, fans, business people, and investors. Product Hunt is a place where those different people connect to build and discuss products.

Products are different from other art forms in that they are measured not only through the lens of design and beauty–but also through utility. From software to books to couches to toiletry–we all have products that have improved our lives so much that we feel a deep sense of connection and hope for that product and the people behind it.

Ryan Hoover is the founder of Product Hunt, a product I have found tremendous value and satisfaction from over the years. He is also a host of Product Hunt Radio, a weekly podcast with the people creating and exploring the future.

Ryan joins the show to discuss products, the process of creating something useful, and his investing strategy. Ryan runs the Weekend Fund, an early stage investment fund.

", + "Episodes Title": "Products with Ryan Hoover", + "Episodes Uid": "SED2584678245", + "Episodes Audio File": "fab1c166185ba570085f2345f701fc57.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5a9", + "Episodes ID": "ef8b366a-e328-11ea-91a2-07336c754f7f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_01_TylerCowen.mp3", + "Episodes Pubdate Date": "2019-02-01", + "Episodes Summary": "

Tyler Cowen’s book Stubborn Attachments outlines a framework that individuals can use to make decisions grounded in economic philosophy. In his previous books, Tyler examined recent economic history. Stubborn Attachments gives his perspective for navigating the future.

Tyler is a professor of economics at George Mason University. He is also the host of Conversations with Tyler, a podcast that includes guests such as Ethereum creator Vitalik Buterin, Stripe co-founder Patrick Collison, and Coinbase CTO Balaji Srinivasan. Tyler blogs frequently at Marginal Revolution.

Tyler’s previous appearance on Software Engineering Daily centered around his earlier books, including The Complacent Class. In this episode, Tyler describes the philosophy outlined in Stubborn Attachments, then we discuss how his philosophy relates to software engineering, podcasting, and economics.

To find all 900 of our old episodes, including past episodes with writers, entrepreneurs, and venture capitalists, check out the Software Engineering Daily app in the iOS and Android app stores. Whether or not you are a software engineer, we have lots of content about technology, business, and culture. In our app, you can also become a paid subscriber and get ad-free episodes–and you can have conversations with other members of the Software Engineering Daily community.

", + "Episodes Title": "Engineering Philosophy with Tyler Cowen", + "Episodes Uid": "SED2096481443", + "Episodes Audio File": "726779236b154f5cf792cbbbcdcbecc3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2tr", + "Episodes ID": "f896f1cc-e328-11ea-91a2-f79eea96784b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Hackathons.mp3", + "Episodes Pubdate Date": "2017-06-22", + "Episodes Summary": "

Professional hackathon programmers travel around the hackathon circuit, winning merchandise and small cash prizes. There are enough hackathons that some programmers actually do this as a full-time job. For example, Peter Ma, a programmer who describes himself as a “rapid prototype specialist.” Peter is a great programmer, and he has received lots of offers to work at big tech companies. What drives him to stay independent and work on hackathon projects?

There are other types of corporate hackathons. Many of us are familiar with the hackathon where a manager orders pizza and suggests that everyone stays at the office late fixing bugs. Some hackathons are held for kids, to get them exposed to technologies early on.

Lizette Chapman is a reporter at Bloomberg, where she writes about technology, business, and news. I was fascinated by her story about hackathons, and it was great to have her on the show to talk about the characters of the hackathon circuit, and why corporations sponsor hackathons.

Lizette has co-hosted the Bloomberg Decrypted podcast in an episode about hackathons. Decrypted is one of my favorite podcasts and I recommend checking it out.

These Hackathon Hustlers Make Their Living from Corporate Coding Contests

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Hackathons with Lizette Chapman", + "Episodes Uid": "SED9275292507", + "Episodes Audio File": "684568810bd7282c8def70cbcc6c3cda.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2m4", + "Episodes ID": "ff6a472e-e328-11ea-91a2-67937dd3c8e3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/microservicesmacro_edited.mp3", + "Episodes Pubdate Date": "2017-04-20", + "Episodes Summary": "

The word “microservices” started getting used after a series of events–companies were moving to cloud virtual machines. Those VMs got broken up into containers, and the containers can fit to the size of the service. Services that are more narrowly defined take up smaller containers, and can be packed more densely into the virtual machines–hence the term “microservices.”

As this change to software architecture has occurred, the DevOps movement has encouraged organizations to have better relationships between development and operations. Continuous deployment leads to fewer painful outages. Improved monitoring tools make it easier for developers to take on some of the pain that was previously centralized in operations.

Several months ago, I attended the Microservices Practitioner Summit, which brings together engineers who are working with microservices at their companies. The conference was organized by Austin Gunter and Richard Li of Datawire. In this episode, they joined me for a conversation about microservices.

Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

", + "Episodes Title": "Microservices Practitioners with Austin Gunter and Richard Li", + "Episodes Uid": "SED1084531549", + "Episodes Audio File": "48515d05b994a47b582bc726c7b54af8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5wg", + "Episodes ID": "ed702f98-e328-11ea-91a2-6f5fb05b4caa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_02_GoogleEarthWebAssembly.mp3", + "Episodes Pubdate Date": "2019-07-02", + "Episodes Summary": "

Google Earth allows users to explore the imagery of the real world. Imagery for Google Earth is taken from satellites, cars equipped with cameras, and other sources. Google Earth renders a data intensive 3-D model of the world on a client application such as a desktop browser or virtual reality system. 

WebAssembly is a runtime for executing code other than JavaScript in a browser-based environment. WebAssembly is useful for data-intensive workloads, and developers can use programming languages such as Rust or C++ in the browser by compiling to WebAssembly.

Jordon Mears works on Google Earth, and he joins the show to talk about the engineering behind Google Earth and how WebAssembly is being used to improve efficiency. He also discusses the state of tooling around WebAssembly today. 

", + "Episodes Title": "Google Earth WebAssembly with Jordon Mears", + "Episodes Uid": "SED6470284599", + "Episodes Audio File": "dfcd535212a6eadf70ce30c8b1d0dd19.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4vg", + "Episodes ID": "f0a98380-e328-11ea-91a2-af0b57dad874", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_06_OSSCapital.mp3", + "Episodes Pubdate Date": "2018-11-06", + "Episodes Summary": "

Open source projects benefit from the network effects of a large audience of developers. A popular open source project will be contributed to and used by thousands of developers, who are continuously testing, deploying, and improving the software. The open source movement has created massive communities and a thriving, collaborative economy.

Infrastructure software companies are increasingly built within an open source business model. Databases, queueing systems, orchestrators, operating systems, and search engines have been started as freely available open source projects, and leveraged into billion dollar businesses. In previous shows we have talked about business strategy, go-to-market tactics, and licensing of infrastructure software.

There remains plenty of room for more open source infrastructure companies. We still need better databases and distributed systems management. But over time, open source will move up the stack. From Netflix to Uber to social networks to payments systems–all software verticals will become open source because the benefits of making your software open source outweigh the costs.

For many software business models, the competitive advantage is not found in their source code–it’s in their data, their network effects, their sales strategy, and their brand.

Therefore, it makes sense that someday the source code will be freely available, democratizing the infrastructure concerns and letting these software businesses move up the value chain and become less operationally intensive at the bottom of the stack. Rather than asking “why should we open source our code”, these companies will be asking “why shouldn’t we open source our code?”

Joseph Jacks is the founder of OSS Capital, a venture capital firm that invests exclusively in commercial OSS startup companies. Joe believes that over time, open source eats everything. In today’s show, we talk about the future of open source businesses, the impact of licensing, cloud providers, and cryptocurrencies.

", + "Episodes Title": "OSS Capital with Joseph Jacks", + "Episodes Uid": "SED1524166124", + "Episodes Audio File": "13ffe987f16004eda1acf66afad2fb65.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2b3", + "Episodes ID": "0fcd666e-e329-11ea-91a2-87ea3b2cd649", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/dotnetcore_edited.mp3", + "Episodes Pubdate Date": "2016-11-29", + "Episodes Summary": "

C# .NET is the framework that is most often used to write software for the Microsoft Windows operating system. For many years, the C# .NET framework was closed source, but Microsoft’s recent push towards open source has led to the creation of .NET Core, a fork of C# .NET composed of a small subset of features from the original C# .NET stack.

This episode takes us through a history of .NET, with two program managers who have worked on .NET for many years–Immo Landwerth and Lee Coward. We also explored the present and future of .NET–discussing .NET Core and .NET usage on operating systems other than Microsoft Windows, which is another recent development.

", + "Episodes Title": "DotNet Core with Lee Coward and Immo Landwerth", + "Episodes Uid": "SED6968990035", + "Episodes Audio File": "ca51d2765aa238f268e0cee02697dc8b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32n", + "Episodes ID": "f6565aa6-e328-11ea-91a2-631cbabefdb2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/StaticAnalysis.mp3", + "Episodes Pubdate Date": "2017-09-25", + "Episodes Summary": "

Static analysis is the process of evaluating code for errors, memory leaks, and security vulnerabilities. The “static” part refers to the fact that the code is not running. This differentiates it from unit tests and integration tests, which evaluate the runtime characteristics of code.

If you use an IDE or a linter, you are using a basic form of static analysis all the time. More sophisticated static analysis tools can be used to analyze code in sensitive domains like healthcare or automobiles.

During static analysis, we can discover problems in the code by evaluating the structure of a program. Buffer overruns can be identified before they turn into a vulnerability like Heartbleed. Null pointer exceptions can be fixed before they cause a segmentation fault. Concurrency issues can be serialized before they result in a problematic race condition.

Today’s guest Paul Anderson is the VP of engineering at GrammaTech, where he works on CodeSonar, a static analysis tool. We discussed how static analysis works, why it is useful, and how it fits into a modern software delivery pipeline. Full disclosure: GrammaTech is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Static Analysis with Paul Anderson", + "Episodes Uid": "SED3482539830", + "Episodes Audio File": "8dd08a11c9d37591923379423aed7acf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3pk", + "Episodes ID": "f34e1e7a-e328-11ea-91a2-c302d117aa21", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_28_KeybaseArchitectureClarifaiInfrastructure.mp3", + "Episodes Pubdate Date": "2018-04-28", + "Episodes Summary": "

Keybase is a platform for managing public key infrastructure. Keybase’s products simplify the complicated process of associating your identity with a public key. Keybase is the subject of the first half of today’s show. Michael Maxim, an engineer from Keybase gives an overview for how the technology works and what kinds of applications Keybase unlocks.

The second half of today’s show is about Clarifai. Clarifai is an AI platform that provides image recognition APIs as a service. Habib Talavati explains how Clarifai’s infrastructure processes requests, and the opportunities for improving the efficiency of that infrastructure.

Last month, we had three Software Engineering Daily Meetups: in New York, Boston, and Los Angeles. At each of these Meetups, listeners from the SE Daily community got to meet each other and talk about software–what they are building and what they are excited about. I was happy to be in attendance at each of these, and I am posting the talks given by our presenters. The audio quality is not perfect on these, but there are also no ads.

Thanks to Datadog for graciously providing a space for our Meetup, and for being a sponsor of SE Daily. You can sign up for Datadog and get a free t-shirt by going to softwareengineeringdaily.com/datadog.

We’d love to have you as part of our community. We will have more Meetups eventually, and you can be notified of these by signing up for our newsletter. Come to SoftwareDaily.com and get involved with the discussion of episodes and software projects. You can also check out our open source projects–the mobile apps, and our website.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Keybase Architecture / Clarifai Infrastructure Meetup Talks", + "Episodes Uid": "SED8709089477", + "Episodes Audio File": "9aab5fe74b6ae9fee2ab7faee8aab608.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5n7", + "Episodes ID": "ee4f3dbe-e328-11ea-91a2-37cee2f150b4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_29_LyftDataPlatform.mp3", + "Episodes Pubdate Date": "2019-04-29", + "Episodes Summary": "

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

Lyft generates petabytes of data. Driver and rider behavior, pricing information, the movement of cars through space; all of this data is received by Lyft’s backend services, buffered into Kafka queues, and processed by various stream processing systems.

Lyft moves the high volumes of data into a data lake for different users throughout the company to use offline. Machine learning jobs, batch jobs, streaming jobs and materialized databases can be created on top of that data lake. Druid and Superset are used for operational analytics and dashboarding.

Li Gao is a data engineer at Lyft. He joins the show to explore the different aspects of Lyft’s data platform. We also talk about the tradeoffs of streaming frameworks, and how to manage machine learning infrastructure. This episode is a great companion to our show about Uber’s data platform, and illustrates some fundamental differences in how the two ridesharing companies operate.

", + "Episodes Title": "Lyft’s Data Platform with Li Gao", + "Episodes Uid": "SED2592587513", + "Episodes Audio File": "be9b56e4ff00e4abaa063f088f72c0fe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3bb", + "Episodes ID": "f5358ef8-e328-11ea-91a2-2fd1dacd6e5f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Scalyr.mp3", + "Episodes Pubdate Date": "2017-12-15", + "Episodes Summary": "

Google Docs is used by millions of people to collaborate on documents together. With today’s technology, you could spend a weekend coding and build a basic version of a collaborative text editor. But in 2004 it was not so easy.

In 2004 Steve Newman built a product called Writely, which allowed users to collaborate on documents together. Initially, Writely was hosted on a single server that Steve managed himself. All of the reads and writes to the documents went through that single server. Writely rapidly grew in popularity, and Steve went through a crash course in distributed systems as he tried to keep up with the user base.

In 2006, Writely was acquired by Google, and Steve spent his next four years turning Writely into Google Docs. Eventually he moved onto other projects within Google—“Cosmo” and “Megastore Replication.” When Steve left the company in 2010, he took with him the lessons of logging and monitoring that keep Google’s infrastructure observable.

Large organizations have terabytes of log data to manage. This data streams off the servers that are running our applications. That log data gets processed in a “metrics pipeline” and turned into monitoring data. Monitoring data aggregates log data in a more presentable format.

Most of the log messages that get created will never be seen with human eyes. These logs get aggregated into metrics, then compressed, and (in many cases) eventually thrown away. Different companies have different sensitivity around their logs, so some companies may not garbage collect any of their logs!

When a problem occurs in our infrastructure, we need to be able to dig into our terabytes of log data and quickly find the root cause of a problem. If our log data is compressed and stored on disk, it will take longer to access it. But if we keep all of our logs in memory, it could get expensive.

To review: if I want to build a logging system from scratch today I need to build: a metrics pipeline for converting log data into monitoring data; a complicated caching system, a way to store and compress logs; a query engine that knows how to ask questions to the log storage system; a user interface so I don’t have to inspect these logs via command line…

The list of requirements goes on and on—which is why there is a huge industry around log management. And logging keeps evolving!  One example we covered recently is distributed tracing, which is used to diagnose requests that travel through multiple endpoints.

After Steve Newman left Google, he started Scalyr, a product that allows developers to consume, store, and query log messages. I was looking forward to talking to Steve about data engineering, and the query engine that Scalyr has architected, but we actually spent most of our conversation talking about the early days of Writely, and his time at Google—particularly the operational challenges of Google’s infrastructure. Full disclosure: Scalyr is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "High Volume Logging with Steve Newman", + "Episodes Uid": "SED8717075856", + "Episodes Audio File": "c3c348ae6cb23816f2827ec5a13859b7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "31g", + "Episodes ID": "f694181e-e328-11ea-91a2-c37426aa8a04", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SecurityChrisCraig.mp3", + "Episodes Pubdate Date": "2017-09-06", + "Episodes Summary": "

Ransomware and DDoS attacks happen all the time. Sometimes they affect large swaths of users. WannaCry ransomware froze the computer systems in hospitals. Mirai botnet DDoS attacks took down a DNS provider, making Netflix and Twitter inaccessible for a short period of time.

These are innocent attacks compared to what we could face from a world where cars, heart rate monitors, and other safety critical machinery become connected to the Internet. This is not a new subject–we have covered it in previous episodes about security. But it’s a deep subject, and there is much ground to cover.

Chris Craig joins the show for this episode–he is a security researcher at Oak Ridge National Lab. He studies network and cloud security, and in this episode he brings his broad expertise to subjects like IoT security, car security, and the question of standards–what do we need to standardize and certify as the internet becomes connected to physical infrastructure?

Thanks to Jared Smith for the introduction.

When Safety and Security Become One

Standardisation and Certification of the ‘Internet of Things’

", + "Episodes Title": "Car and IoT Security with Chris Craig", + "Episodes Uid": "SED6344712639", + "Episodes Audio File": "734d12434526e67e6a5c5104386e4d9a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5cq", + "Episodes ID": "ef53d620-e328-11ea-91a2-93fa1981f66e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_19_Store2Vec.mp3", + "Episodes Pubdate Date": "2019-02-19", + "Episodes Summary": "

DoorDash is a food delivery company where users find restaurants to order from. When a user opens the DoorDash app, the user can search for types of food or specific restaurants from the search bar or they can scroll through the feed section and look at recommendations that the app gives them within their local geographic area.

Recommendations is a classic computer science problem. Much like sorting, or mapping, or scheduling, we will probably never “solve” recommendations. We will adapt our recommendation systems based off of discoveries in computer science and software engineering.

One pattern that has been utilized recently by software engineers in many different areas is the “word2vec”-style strategy of embedding entities in a vector space and then finding relationships between them. If you have never heard of the word2vec algorithm, you can listen to the episode we did with computer scientist and venture capitalist Adrian Colyer or listen to this episode in which we will describe the algorithm with a few brief examples.

Store2vec is a strategy used by DoorDash to model restaurants in vector space and find relationships between them in order to generate recommendations. Mitchell Koch is a senior data scientist with DoorDash, and he joins the show to discuss the application of store2vec, and the more general strategy of word2vec-like systems. This episode is also a great companion to our episode about data infrastructure at DoorDash.

", + "Episodes Title": "Store2Vec: DoorDash Recommendations with Mitchell Koch", + "Episodes Uid": "SED1506721015", + "Episodes Audio File": "ff62478236b4f7990cdb8b902c087bd3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4oy", + "Episodes ID": "f102de12-e328-11ea-91a2-6fd078f7ce1a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_11_GenerativeModels.mp3", + "Episodes Pubdate Date": "2018-10-11", + "Episodes Summary": "

Google Brain is an engineering team focused on deep learning research and applications. One growing area of interest within Google Brain is that of generative models. A generative model uses neural networks and a large data set to create new data similar to the ones that the network has seen before.

One approach to making use of generative models is GANs: generative adversarial networks. GANs can use a generative model (which creates new examples) together with a discriminator model (which can classify examples).

As an example, let’s take the task of generating new pictures of cats. We want an artificial cat picture generator. First, we train a discriminator by feeding it billions of example pictures of cats. We now have a model that can tell what a cat is. Next, we make a model that generates completely random images. We feed those randomly generated images to the discriminator. The discriminator outputs a “loss” for these random images. Loss is a metric we can use to represent how far off a given image is from being something that the discriminator would recognize as a cat. Finally, you can feed this “loss” back into the generative model, so that the generative model will adjust its weights in a way that will reduce loss. Over time, the generator gets better and better at reducing loss, until the discriminator starts believing that some of these semi-random images are actually cats.

Generative model systems have produced useful applications, such as object detection, image editing, and text-to-image generation. Today’s guest Doug Eck works on the Magenta team at Google Brain. Magenta uses applications of deep learning to produce tools and experiments around music, art, and creativity.

In a previous show, Doug described his vision for humans and computers to work together on creative tasks such as music. Today, we dive into some of the core machine learning building blocks that make machine creativity possible.

", + "Episodes Title": "Generative Models with Doug Eck", + "Episodes Uid": "SED9906352521", + "Episodes Audio File": "3a7bcd766e1be8324eea83087ba0071d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2fb", + "Episodes ID": "0a42acd6-e329-11ea-91a2-077a0e04728e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ionic_edited.mp3", + "Episodes Pubdate Date": "2017-01-23", + "Episodes Summary": "

Building a mobile app requires developers to build a separate version for Android and iOS. The approval process for app stores makes it difficult to deploy quickly and iterate in small batches for developers who are making native apps. These frictions cause fewer developers to write mobile apps than we would have if the smartphone platform was unified.

Since the early days of the smartphone, different cross platform solutions have been tried, and many developers got burned after they implemented an app that was supposed to work on iOS and Android, when the performance ended up being poor on both. Today, the cross-platform solutions are finally getting good with frameworks like React Native and Ionic.

Ionic allows developers to write apps in AngularJS and deploy them to both Android and iOS. In this episode, Adam Bradley from Ionic gives a brief history of cross-platform apps, and explains what is different today–and why cross platform apps are exploding in popularity, particularly in large enterprises.

", + "Episodes Title": "Hybrid Mobile Apps with Adam Bradley", + "Episodes Uid": "SED2514765452", + "Episodes Audio File": "7e66030a555fe0c776409e6ce36df9eb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jw", + "Episodes ID": "0316c258-e329-11ea-91a2-2f556d1eeaff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ProductDevelopment.mp3", + "Episodes Pubdate Date": "2017-03-27", + "Episodes Summary": "

Developing a product requires careful balance between engineering, sales, design, and customer service. The founding CTO of a company often needs to take on each of these responsibilities, because when the company only has a few people there is nobody to delegate these different tasks to.

Cullen Zandstra is the CTO at FloQast, a SaaS tool for accounting close management. It isn’t important what that means–we do describe it in this episode, but the actual software product that we are discussing is less important than the general discussions we have. Cullen gives detailed explanations for how to develop a software product.

In the past, Cullen worked at MySpace. After we discussed his current company FloQast, we discussed some of what he learned at MySpace, and why the social network proved to be less durable than Facebook. We also had some great discussion as to why Google+ was ALSO less durable than Facebook.

Also–I should mention that FloQast is hiring engineers in their Los Angeles office. And thanks to my friend Patrick Mathieson for connecting Cullen and myself.

", + "Episodes Title": "Product Development with Cullen Zandstra", + "Episodes Uid": "SED6942871447", + "Episodes Audio File": "b2285f00fb85c0945afb1078f917abf9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4id", + "Episodes ID": "f149f11c-e328-11ea-91a2-9373bc992e7a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_19_AndroidonChrome.mp3", + "Episodes Pubdate Date": "2018-09-20", + "Episodes Summary": "

Google has two consumer operating systems: Android and Chrome. The Android operating system has been widely deployed on mobile devices. Chrome is an operating system for laptops and tablets, originally based around the Chrome browser.

For several years, these two ecosystems were mostly separate–you could not run Android apps on a Chrome operating system. Shahid Hussain and Stefan Kuhne are engineers at Google who worked on support for Android apps on ChromeOS. The implementation of Android on Chrome involves running the Android OS in a Linux container on the host Chrome operating system.

In today’s episode, Shahid and Stefan compare the Android and Chrome operating system platforms. They explain why Google has two different consumer operating systems, and the advantages of allowing Android apps to deploy to Chrome.

Shahid and Stefan also talk about the challenges of porting mobile applications to ChromeOS. Android apps are made to run on small screens and tablets. In order to make them run on ChromeOS, the applications need to support running on a desktop or laptop.

", + "Episodes Title": "Android on Chrome with Shahid Hussain and Stefan Kuhne", + "Episodes Uid": "SED7897897233", + "Episodes Audio File": "f093ad10cb5e67bd57a7f4e87777c456.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 612, + "Episodes ID": "ece2470a-e328-11ea-91a2-073f4e54c099", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_07_PeopleaiMachineLearning.mp3", + "Episodes Pubdate Date": "2019-08-07", + "Episodes Summary": "

A large sales organization has hundreds of sales people. Each of those sales people manages a set of accounts who they are trying to close sales deals on. Sales people are overseen by managers who ensure that the sales people are performing well. Directors and VPs ensure the scalability and health of the overall sales organization.

The sales lifecycle mostly takes place within a piece of software called a CRM: customer relationship management. This tool documents the interactions between sales people and accounts. CRMs have been around for many years, and although CRM software is a useful repository of data, it does not fulfill all the needs of a salesperson.

People.ai is a system of machine learning tools built around the sales tooling ecosystem. People.ai helps a sales organization avoid manual data entry, understand areas of potential improvement, and decide on who the highest value sales lead to pursue might be. Andrey Akselrod is the CTO At People.ai and he joins the show to discuss the potential applications of machine learning in the domain of sales, and the engineering work that his company has done.

", + "Episodes Title": "People.ai: Machine Learning for Sales with Andrey Akselrod", + "Episodes Uid": "SED9113777416", + "Episodes Audio File": "092732ea0e955ab59e391055d415595f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2kc", + "Episodes ID": "02d3eadc-e329-11ea-91a2-cfe0ac53235c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/gremlin_edited.mp3", + "Episodes Pubdate Date": "2017-03-29", + "Episodes Summary": "

Servers in a data center fail. Sometimes entire data centers have a power outage. Bugs in an application make it into production. Human operators make mistakes and cause data to be deleted.

Failure is unavoidable. We make backups and replicate our servers so that when a failure occurs, we can quickly respond to it without making the user feel much pain. But how can we test that our response will work before an actual catastrophe occurs?

Kolton Andrus is CEO of Gremlin, a company that works on failure injection as a service. Gremlin is based on ideas around planned failure that Kolton learned from his years at Amazon and Netflix.

We ended up talking as much about the culture of Netflix and Amazon as we did about how and why to build failure injection. It’s always nice to share war stories with other people who have worked at Amazon because the culture is so distinct. If you want to know more about Amazon’s culture, check out the episode tomorrow with Brad Stone, author of The Everything Store.

", + "Episodes Title": "Failure Injection with Kolton Andrus", + "Episodes Uid": "SED2281393758", + "Episodes Audio File": "dc714a28f830611b1b5b11f154a51d85.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32r", + "Episodes ID": "f646ac8c-e328-11ea-91a2-1b2cab2b9aca", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ClementPang.mp3", + "Episodes Pubdate Date": "2017-09-28", + "Episodes Summary": "

An alert is a signal of problematic application behavior. When something unusual happens to your application, an alert can bring that anomaly to your attention. In order to detect unusual events, you need to define the norm.

In order to define both normal and problematic behavior, you need metrics. Metrics are measurements of the behavior in your application. Metrics get created from logs and other data. These high volumes of data get aggregated and collected into easily digestible metrics. This aggregation process that reduces data to metrics is often called a “metrics pipeline.”

Clement Pang is the chief architect of Wavefront, a company that builds metrics and alerting software for enterprises such as Box and Lyft. Clement joins the show to discuss how enterprises use alerting and metrics and how to build a company around metrics and alerting–including the data engineering involved in constructing a metrics pipeline.

The iOS app is the first project to come out of the Software Engineering Daily Open Source Project. There are more projects on the way, and we are looking for contributors–if you want to help build a better SE Daily experience, check out github.com/softwareengineeringdaily. We are working on an Android app, the iOS app, a recommendation system, and a web frontend. Help us build a new way to consume software engineering content at github.com/softwareengineeringdaily.

", + "Episodes Title": "Alerting and Metrics with Clement Pang", + "Episodes Uid": "SED9362084089", + "Episodes Audio File": "e357accfacc374e190cb2e89df50e37b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "47j", + "Episodes ID": "f22276a4-e328-11ea-91a2-1fc360e952a0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_23_KubernetesinEnterprise.mp3", + "Episodes Pubdate Date": "2018-07-23", + "Episodes Summary": "

Enterprises want to update their technology faster. One way an enterprise can accelerate the adoption of new tools is to move more aggressively towards the cloud. By giving internal developers access to the cloud, it becomes easier to provision new servers–allowing for rapid experimentation, test environments, and scalability.

In previous shows we have explored how large enterprises successfully learn to move their technology faster. Much of this process is rooted in being able to experiment quickly–which requires well-defined testing procedures, and the ability to quickly provision and destroy infrastructure.

Many enterprises have large on-premise infrastructure deployments. An enterprise’s movement towards the cloud can be made complex by this existing set of servers.

In today’s show, Aparna Sinha discusses how Kubernetes is useful for enterprises–and how it can improve development speed, experimentation, and observability. Aparna is the leader of the product team for Kubernetes and Container Engine at Google. Much of her job is centered around understanding what would be useful to enterprises who are choosing a cloud provider.

The open source version of Kubernetes is useful on its own, but most enterprises choose a managed provider of Kubernetes–such as Google Kubernetes Engine–to help with support and onboarding . Full disclosure: Google is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Kubernetes in the Enterprise with Aparna Sinha", + "Episodes Uid": "SED3754086156", + "Episodes Audio File": "81dfdab67de77812cba9f095af6f5b6b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3pp", + "Episodes ID": "f336c752-e328-11ea-91a2-cf1890d3e1b9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_04_GeospatialAnalytics.mp3", + "Episodes Pubdate Date": "2018-05-04", + "Episodes Summary": "

Phones are constantly tracking the location of a user in space. Devices like cars, smart watches, and drones are also picking up high volumes of location data. This location data is also called “geospatial data.”

The amount of geospatial data is rapidly increasing, and there is a growing demand for software to perform operations over that data. Geospatial data sets are often massive–so it is non-trivial to perform operations over this data.

Geospatial data can consist of something as simple as a set of latitude/longitude data points. A single lat/long coordinate pair can be enriched with information about what ZIP code it is in, how far that data point is from the other data points in the set, and where the nearest coffee shop is in relation to that data point.

Ram Sriharsha created Magellan, a geospatial analytics library for Spark. In today’s show, Ram describes the set of problems within the domain of geospatial analytics engineering. Ram also works as a product manager for Apache Spark at Databricks.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Spark Geospatial Analytics with Ram Sriharsha", + "Episodes Uid": "SED2788475541", + "Episodes Audio File": "3563e9e8c207515b36dc9c24e6f6f508.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2qi", + "Episodes ID": "fab1b672-e328-11ea-91a2-ab872a3f74ed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/UniversalHealthcare.mp3", + "Episodes Pubdate Date": "2017-05-25", + "Episodes Summary": "

Everyone in the world should have some basic level of guaranteed healthcare. This is not controversial. But what should that basic level of healthcare be? Should it extend into the later years of your life, when the majority of your health costs are incurred? And how much has modern technology driven down the cost of what it should cost to treat a patient?

Healthcare today has lots of problems with bureaucracy and poorly aligned incentives. But the potential of vastly better healthcare is clear to technologists, and advances in software in hardware that have benefited other enterprises will eventually make their way into healthcare–reducing cost, improving oversight, and leading to better health.

Watsi is a non-profit with the goal of seeing a world with universal healthcare. Watsi facilitates crowdfunding of patients who need low-cost, high-impact treatment. Y-Combinator Research recently funded a study in collaboration with Watsi to study using technology to improve the quality and reduce the cost of healthcare.

Thomas Bukowski is a software engineer with Watsi, and he joins me for an interview about what universal healthcare means and what the roadmap to getting there might look like.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Universal Healthcare with Thomas Bukowski", + "Episodes Uid": "SED7761866514", + "Episodes Audio File": "13e4f9ed9b169e0f5279622915020e0c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "63e", + "Episodes ID": "eca71338-e328-11ea-91a2-df2a07eb325c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_23_CryptoOpenSource.mp3", + "Episodes Pubdate Date": "2019-08-23", + "Episodes Summary": "

Cryptocurrencies are decentralized monetary systems built on open source software.

The open source software movement has evolved from the world of Linux, MySQL, and Apache to a thriving ecosystem of commercial enterprises built around open source software. This ecosystem includes projects such as Kubernetes, MongoDB, and ReactJS. It includes large organizations such as Amazon Web Services, Elastic, and Facebook.

In a parallel software universe, the crypto ecosystem has built revolutionary new financial tools, creating billions of dollars of value, but not very many massive commercial companies.  In the world of cryptocurrencies, many of the same rules apply to the classic open source world. But other rules do not. 

How do these two worlds differ from each other? How are they the same? And how might they end up colliding?

Haseeb Qureshi, Joseph Jacks, and Alok Vasudev join the show for a spirited discussion of cryptocurrencies and open source. Haseeb is a cryptocurrency investor, JJ is the founder of OSS Capital, and Alok is an engineer and the founder of crypto venture capital firm Standard Crypto.

", + "Episodes Title": "Crypto and OSS with Haseeb Qureshi, Joseph Jacks, and Alok Vasudev", + "Episodes Uid": "SED9103882569", + "Episodes Audio File": "dca3ca049e005a2071e887419e0a1473.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ln", + "Episodes ID": "f3cf05c6-e328-11ea-91a2-cfabfa775947", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_23_SlockitwithChristophJentzsh.mp3", + "Episodes Pubdate Date": "2018-03-23", + "Episodes Summary": "

The DAO was a system of smart contracts on the Ethereum blockchain that investors put millions of dollars into. Back in May 2016, it was the largest crowdfunding event in history, and we discussed it in detail in a previous episode with Matt Leising. The DAO was hacked due to a security vulnerability, and this event led to a hard fork of Ethereum.

The DAO was organized by a company called Slock.it. Slock.it’s original goal was to allow people to connect devices to the Ethereum blockchain. If you could connect smart locks, cars, and electricity systems to the blockchain, it could create decentralized systems for sharing these devices. To raise money, Slock.it created the DAO. Although the initial scope of the DAO was to raise money for Slock.it, over time it expanded in scope to become a decentralized system for venture capital.

When the DAO was hacked, the events that followed shook the Ethereum community. The hard fork lowered the financial damage inflicted on the investors–but there was still outrage within the community. How was it possible for an open source crowdfunding project to launch with a security vulnerability? As the Ethereum world looked for someone to blame, they turned to Slock.it.

Thus began a very difficult period in the life of Christoph Jentzsch. Christoph is the CEO of Slock.it, and he has been involved in the Ethereum community since the early days. When people think of Slock.it, they might imagine a group of people that move fast and break things. But in fact, Christoph’s early work on Ethereum was around rigorous unit testing of different Ethereum clients. He was obsessed with testing, and consistency between the different Ethereum interfaces.

In today’s episode, Christoph and I talk about his early experiences with Ethereum, his reflections on the events of the DAO, and the direction that Slock.it is going today. Since the events of the DAO, the company has refocused its efforts on the original mission–to connect devices to the Ethereum blockchain.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

If you are looking for all 700 episodes of Software Engineering Daily, check out our apps on the iOS or Android app store. We’ve got tons of episodes on blockchains, business, distributed systems, and tons of other topics. If you want to become a paid subscriber to Software Engineering Daily, you can hear all of our episodes without ads–you can subscribe at softwaredaily.com. And all of the code for our apps is open source. If you are looking for an open source community to be a part of, come check out github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "DAO Reflections and Slock.it with Christoph Jentzsch", + "Episodes Uid": "SED7757435967", + "Episodes Audio File": "742059d611abd866636958b248068fb1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jm", + "Episodes ID": "038c408c-e329-11ea-91a2-27aa40b98cce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Zcash.mp3", + "Episodes Pubdate Date": "2017-03-23", + "Episodes Summary": "

In bitcoin, every transaction in the shared ledger has the sender, recipient, and value. This ledger gets appended infinitely and is shared within a peer-to-peer network. Zcash is a cryptocurrency with all the features of bitcoin, plus encrypted transactions. The sender, recipient, and value fields are all encrypted.

If bitcoin is HTTP, Zcash is like HTTPS, a secure transport layer. Nathan Wilcox works on Zcash, and in this episode we discuss why an encrypted version of bitcoin is useful, how mining works, and how Zcash the company is structured. Nathan also gives some context for the current state of the bitcoin community, and where Zcash fits in.

", + "Episodes Title": "Zcash with Nathan Wilcox", + "Episodes Uid": "SED3342318764", + "Episodes Audio File": "2e028727659b224f17fb1f5ef5aad747.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48t", + "Episodes ID": "f19c5ccc-e328-11ea-91a2-c344cb1594b9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_23_StitchfixCTO.mp3", + "Episodes Pubdate Date": "2018-08-23", + "Episodes Summary": "

Stitch Fix is a company that recommends packages of clothing based on a set of preferences that the user defines and updates over time. Stitch Fix’s software platform includes the website, data engineering infrastructure, and warehouse software. Stitch Fix has over 5000 employees, including a large team of engineers.

Cathy Polinsky is the CTO of Stitch Fix. In today’s show Cathy describes how the infrastructure has changed as the company has grown–including the process of moving the platform from Heroku to AWS, and the experience of scaling and refactoring a large monolithic database. Cathy also talked about the management structure, the hiring process, and engineering compensation at Stitch Fix.

", + "Episodes Title": "StitchFix Engineering with Cathy Polinsky", + "Episodes Uid": "SED2944788168", + "Episodes Audio File": "ee16c71e4a991edd6ce3118c2b2d3b76.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "44x", + "Episodes ID": "f25dd1a4-e328-11ea-91a2-2770bf31ea8d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_05_Vizai.mp3", + "Episodes Pubdate Date": "2018-07-05", + "Episodes Summary": "

When a patient comes into the hospital with stroke symptoms, the hospital will give that patient a CAT scan, a 3-dimensional imaging of the patient’s brain. The CAT scan needs to be examined by a radiologist, and the radiologist will decide whether to refer the patient to an interventionist–a surgeon who can perform an operation to lower the risk of long-term damage to the patient’s brain function.

After getting the CAT scan, the patient might wait for hours before a radiologist has a chance to look at the scan. In that period of time, the patient’s brain function might be rapidly degrading. To speed up this workflow, a company called Viz.ai built a machine learning model that can recognize whether a patient is at high risk of stroke consequences or not.

Many people have predicted that radiologists will be automated away by machine learning in the coming years. This episode presents a much more realistic perspective: first of all, we don’t have nearly enough radiologists, so if we can create automated radiologists that would be a very good thing; second of all, even in this workflow with a cutting-edge machine learning radiologist, you still need the human radiologist in the loop.

David Golan is the CTO at Viz.ai, and in today’s show he explains why he is working on a system for automated stroke identification, and the engineering challenges in building that system.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Machine Learning Stroke Identification with David Golan", + "Episodes Uid": "SED8800785550", + "Episodes Audio File": "9d557a925af0fbe3b1a106053ec25f14.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3m4", + "Episodes ID": "f3c9abd0-e328-11ea-91a2-1f38f900c640", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_26_Tendermint.mp3", + "Episodes Pubdate Date": "2018-03-26", + "Episodes Summary": "

Consensus protocols are used to allow computers to work together. A consensus protocol lets different servers agree on the state of a system. For decades, these protocols have been used to establish consensus among database nodes, application servers, and other infrastructure that runs within an enterprise. More recently, new consensus protocols have been invented to allow cryptoeconomic systems to agree on the state of a financial system.

The first cryptoeconomic consensus protocol to reach wide adoption was Nakamoto consensus–the proof-of-work system used for consensus of Bitcoin. Since then, other systems have been developed, with different tradeoffs in security, speed, and formal verifiability.

Ethan Buchman is the CTO at Tendermint, a consensus system for blockchains. In addition to working on Tendermint, Ethan works on Cosmos, a network of blockchains. In this episode, we talk about different consensus systems–for centralized, trustworthy systems as well as for trustless systems like currencies.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Consensus Systems with Ethan Buchman", + "Episodes Uid": "SED8764546350", + "Episodes Audio File": "0809fb4f9affb8dde1d91fce0707753b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3gg", + "Episodes ID": "f473bcba-e328-11ea-91a2-075fedb8ddf1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_06_CloudFlareWorkers.mp3", + "Episodes Pubdate Date": "2018-02-06", + "Episodes Summary": "

Over the last decade, computation and storage has moved from on-premise hardware into the cloud data center. Instead of having large servers “on premise,” companies started to outsource their server workloads to cloud service providers.

At the same time, there has been a proliferation of devices at the “edge.” The most common edge device is your smartphone, but there are many other smart devices that are growing in number–drones, smart cars, Nest thermostats, smart refrigerators, IoT sensors, and next generation centrifuges. Each of these devices contains computational hardware.

Another class of edge device is the edge server. Edge servers are used to facilitate faster response times than your core application. For example, Software Engineering Daily uses a content delivery network for audio files. These audio files are distributed throughout the world on edge servers. The core application logic of Software Engineering Daily runs on a WordPress site, and that WordPress application is distributed to far fewer servers than our audio files.

“Cloud computing” and “edge computing” both refer to computers that can serve requests. The “edge” is commonly used to refer to devices that are closer to the user–so they will deliver faster responses. The “cloud” refers to big, bulky servers that can do heavy duty processing workloads–such as training machine learning models, or issuing a large distributed MapReduce query.

As the volume of computation and data increases, we look for better ways to utilize our resources, and we are realizing that the devices at the edge are underutilized.

In today’s episode, Kenton Varda explains how and why to deploy application logic to the edge. He works at Cloudflare on a project called Cloudflare Workers, which are a way to deploy JavaScript to edge servers, such as the hundreds of data centers around the world that are used by Cloudflare for caching.

Kenton was previously on the show to discuss protocol buffers, a project he led while he was at Google. To find that episode, and many other episodes about serverless, download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless at the Edge with Kenton Varda", + "Episodes Uid": "SED1162295036", + "Episodes Audio File": "601ffadeb1316f865b83295ade640d4a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5tb", + "Episodes ID": "edc3a164-e328-11ea-91a2-c3791a6a2333", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_07_KubernetesEcosystemAdamGlick.mp3", + "Episodes Pubdate Date": "2019-06-07", + "Episodes Summary": "

Amazon Web Services is the leading cloud provider by a large margin. Amazon established its lead by being first to market in 2006, with Google and Microsoft taking several years to catch up to the huge business opportunity of the cloud.

Since 2008, Google Cloud has been working on cloud products for developers. It started with App Engine, which is widely used internally at Google, but has not had overwhelming public adoption. Over the last eleven years, Google has refined its understanding of how customers want to buy public cloud resources. Google Cloud products like Cloud Storage, Persistent Disk, and BigTable have given Google parity with many of the AWS public cloud offerings.

Although Google has caught up to AWS in terms of products, the enterprise market has continued to choose AWS as its default. AWS is widely perceived as  having more experience in running enterprise workloads, and a better responsiveness to customers.

In order to keep Amazon from running away with the cloud market entirely, Google needed to shift the competitive landscape to different territory. Kubernetes provided the paradigm shift that Google needed.

The market for cloud providers has changed completely due to Kubernetes. When Google open sourced Kubernetes, it created a common codebase for software companies to build software for managing distributed systems.

In the span of five years, Kubernetes has turned the world of cloud products into a world resembling the open source Linux ecosystem. This is a remarkable shift, and every infrastructure software vendor is still figuring out its strategy for adapting.

Adam Glick is the head of modern infrastructure and serverless marketing at Google. With Craig Box, he hosts the Kubernetes Podcast from Google, an excellent show about recent developments and evergreen concepts within the world of Kubernetes. Prior to Google, Adam worked at AWS for 3 years and Microsoft for twelve years. He has seen each of the major cloud providers up close and has a deep awareness for how each company thinks.

We had a great conversation about the cloud native landscape, podcasting, and developer marketing.

New Software Daily app for iOS. You can become a paid subscriber for ad free episodes at softwareengineeringdaily.com/subscribe

", + "Episodes Title": "Kubernetes Market with Adam Glick", + "Episodes Uid": "SED5863217167", + "Episodes Audio File": "a3b9a9778a0d92b68a1d3f2f7431b54f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2wr", + "Episodes ID": "f735c54c-e328-11ea-91a2-434eeeb6eb07", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ApparelMachineLearning.mp3", + "Episodes Pubdate Date": "2017-07-20", + "Episodes Summary": "

In its most basic definition, machine learning is a tool that makes takes a data set, finds a correlation in that data set, and uses that correlation to improve a system. Any complex system with well-defined behavior and clean data can be improved with machine learning.

Several precipitating forces have caused machine learning to become widely used: more data, cheaper storage, and better tooling. Two pieces of tooling that have been open sourced from Google help tremendously: Kubernetes and TensorFlow.

Kubernetes is not a tool for machine learning, but it simplifies distributed systems operations, unlocking more time for engineers to focus on things that are not as commodifiable–like tweaking machine learning parameters. TensorFlow is a framework for setting up machine learning systems.

Machine learning should affect every aspect of our lives–including tuxedo fitting. Generation Tux is a company that allows customers to rent apparel that historically has required in-person fitting. Using machine learning, they have developed a system that allows customers to get fit for an outfit without entering a brick-and-mortar store.

In this episode, Colan Connon and Thomas Bell from Generation Tux join to explain how Generation Tux adopted Kubernetes and TensorFlow, and how the company’s infrastructure and machine learning pipeline work.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Apparel Machine Learning with Colan Connon and Thomas Bell", + "Episodes Uid": "SED1709170053", + "Episodes Audio File": "670588fa0e3ec3b2086076ac30c44699.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32q", + "Episodes ID": "f64c06c8-e328-11ea-91a2-1f7fcd18689c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/VideoInfrastructure.mp3", + "Episodes Pubdate Date": "2017-09-27", + "Episodes Summary": "

Playing a video on the Internet seems simple. You press play, the video gets delivered, and boom–you are watching Game of Thrones, right?

It’s a bit more complicated. Unless you have built an application that involves video, you probably have not dealt with the world of codecs, bitrates, and streaming. Depending on the bandwidth between the user and the server, you might want to use different compression rates. Think about all of the different use cases–different connection speeds, device types, operating systems, video players, cloud providers. As a developer, you just want videos in your application to play quickly and reliably. But it takes a lot of engineering, monitoring, and re-engineering to get it right.

Matt McClure and Jon Dahl are the founders of Mux, a company that makes video infrastructure technologies. Previously they built Zencoder, a product for encoding and delivering video. This episode was a fascinating discussion of why building video products for the modern Internet is still so hard.

Download the Software Engineering Daily app for iOS to hear all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that.

The iOS app is the first project to come out of the Software Engineering Daily Open Source Project. There are more projects on the way, and we are looking for contributors–if you want to help build a better SE Daily experience, check out github.com/softwareengineeringdaily. We are working on an Android app, the iOS app, a recommendation system, and a web frontend. Help us build a new way to consume software engineering content at github.com/softwareengineeringdaily.

", + "Episodes Title": "Video Infrastructure with Matt McClure and Jon Dahl", + "Episodes Uid": "SED1150430815", + "Episodes Audio File": "53a113ed58e49db6635a8455ba59e086.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 392, + "Episodes ID": "f57a64b0-e328-11ea-91a2-4bd23c953d85", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ThumbtackInfrastructure.mp3", + "Episodes Pubdate Date": "2017-11-28", + "Episodes Summary": "

Thumbtack is a marketplace for real-world services. On Thumbtack, people get their house painted, their dog walked, and their furniture assembled. With 40,000 daily marketplace transactions, the company handles significant traffic.

On yesterday’s episode, we explored how one aspect of Thumbtack’s marketplace recently changed, going from asynchronous matching to synchronous “instant” matching. In this episode, we zoom out to the larger architecture of Thumbtack, and how the company has grown through its adoption of managed services from both AWS and Google Cloud.

The word “serverless” has a few definitions. In the context of today’s episode, serverless is all about managed services like Google BigQuery, Google Cloud PubSub, and Amazon ECS. The majority of infrastructure at Thumbtack is built using services that automatically scale up and down. Application deployment, data engineering, queueing, and databases are almost entirely handled by cloud providers.

For the most part, Thumbtack is a “serverless” company. And it makes sense–if you are building a high-volume marketplace, you are not in the business of keeping servers running. You are in the business of improving your matching algorithms, your user experience, and your overall architecture. Paying for lots of managed services is more expensive than running virtual machines–but Thumbtack saves money from not having to hire site reliability engineers.

Nate Kupp leads the technical infrastructure team, and we met at QCon in San Francisco to talk about how to architect a modern marketplace. This was my third time attending QCon and as always I was impressed by the quality of presentations and conversations I had there. They were also kind enough to set up some dedicated space for podcasters like myself.

The most widely used cloud provider is AWS, but more and more companies that come on the show are starting to use some of the managed services from Google. The great news for developers is that integration between these managed services is pretty easy.

At Thumbtack, the production infrastructure on AWS serves user requests. The log of transactions that occur get pushed from AWS to Google Cloud, where the data engineering occurs. On Google Cloud, the transaction records are queued in Cloud PubSub, a message queueing service. Those transactions are pulled off the queue and stored in BigQuery, a system for storage and querying of high volumes of data.

BigQuery is used as the data lake to pull from when orchestrating machine learning jobs. These machine learning jobs are run in Cloud Dataproc, a managed service that runs Apache Spark. After training a model in Google Cloud, that model is deployed on the AWS side, where it serves user traffic. On the Google Cloud side, the orchestration of these different managed services is done by Apache Airflow, an open source tool that is one of the few pieces of infrastructure that Thumbtack does have to manage themselves on Google Cloud.

To find out more about the Thumbtack infrastructure, check out the video of the talk Nate gave at QCon San Francisco, or check out the Thumbtack Engineering Blog.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Thumbtack Infrastructure with Nate Kupp", + "Episodes Uid": "SED3183609023", + "Episodes Audio File": "375d6f4de2c448e36a5dfc7ac51d3860.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4cz", + "Episodes ID": "f1929110-e328-11ea-91a2-03dc72953b30", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_28_AndroidSlices.mp3", + "Episodes Pubdate Date": "2018-08-28", + "Episodes Summary": "

The main user interfaces today are the smartphone, the laptop, and the desktop computer. Some people today interact with voice interfaces, augmented reality, virtual reality, and automotive computer screens like the Tesla. In the future, these other interfaces will become more common. Developers will want to be able to expose their applications to these new interfaces.

For example, let’s say I am a developer who builds a podcast playing app. I have a website and a mobile app, but what if I want to expose that app to a voice interface? Or, what if I want to expose a specific piece of functionality from that app, to make shortcuts easier?

Android Slices are user interface components that expose pieces of application functionality to Google Search, Google Assistant, and other applications. Jason Monk is a software engineer who works on Android Slices at Google. Jason joins the show to discuss how mobile user interfaces are changing, the motivation behind Android Slices, and the engineering behind this newer building block for Android developers.

", + "Episodes Title": "Android Slices with Jason Monk", + "Episodes Uid": "SED6052491512", + "Episodes Audio File": "4c74260276ba594773e9492ab00e7a19.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2gx", + "Episodes ID": "072d5df2-e329-11ea-91a2-87f709696f5b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DataApps.mp3", + "Episodes Pubdate Date": "2017-02-15", + "Episodes Summary": "

Data scientists need flexible interfaces for displaying and manipulating data sets. Data engineers need to be able to visualize how their data pipelines wire together databases and data processing frameworks. DevOps engineers need dashboards to understand their monitoring data at a high level. All of these programmers are building data applications.

Data applications let us visualize and manipulate data sets effectively. In today’s episode, Dave King joins the show to describe the growing importance of data applications. Many knowledge workers use flexible tools like spreadsheets and business intelligence applications. But when you build a domain specific data application for a knowledge worker, you can unlock a higher degree of leverage for that knowledge worker. We discuss data applications and the future of knowledge work in this episode with Dave King.

Full disclosure: Exaptive is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Data Applications With Dave King", + "Episodes Uid": "SED7425886323", + "Episodes Audio File": "1dc405fcbe87d812a99788ec404633ce.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2h5", + "Episodes ID": "0718a556-e329-11ea-91a2-1716c9d8ed67", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/WhyMLisHard.mp3", + "Episodes Pubdate Date": "2017-02-16", + "Episodes Summary": "

Machine learning frameworks like Torch and TensorFlow have made the job of a machine learning engineer much easier. But machine learning is still hard. Debugging a machine learning model is a slow, messy process.

A bug in a machine learning model does not always mean a complete failure. Your model could continue to deliver usable results even in the presence of a mistaken implementation. Perhaps you made a mistake when cleaning your data, leading to an incorrectly trained model.

It is a general rule in computer science that partial failures are harder to fix than complete failures. In this episode, Zayd Enam describes the different dimensions on which a machine learning model can develop an error. Zayd is a machine learning researcher at the Stanford AI Lab, so I also asked him about AI risk, job displacement, and academia versus industry.

Why ML is hard

", + "Episodes Title": "Machine Learning is Hard with Zayd Enam", + "Episodes Uid": "SED9871701075", + "Episodes Audio File": "5eecc856536c3fb0e455a5feeedb1654.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2hh", + "Episodes ID": "069a8b30-e329-11ea-91a2-777202578b8b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ADChain.mp3", + "Episodes Pubdate Date": "2017-02-21", + "Episodes Summary": "

Online advertising is a system of transactions that involve many different players. The user visits a publisher’s website; the publisher notifies an exchange that the user is on the website; the exchange presents an opportunity to a marketplace that can buy that opportunity to show the end user the ad. And this a simple example.

The transactions in online advertising are as opaque and rife with fraud as Wall Street–but less regulated. Blockchain technology presents an opportunity to bring more transparency to the advertising ecosystem using a shared ledger.

Ken Brook is the CEO of VidRoll, a video advertising company. Using his experience in the adtech business, Ken is working on Adchain, a shared ledger for adtech. In this episode, we explore adtech, blockchains, and Adchain.

Russian Cyberforgers Steal Millions a Day with Fake Sites

", + "Episodes Title": "Adchain with Ken Brook", + "Episodes Uid": "SED7209011684", + "Episodes Audio File": "f0d405c8df38f51730e23b6cc4e13936.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5u7", + "Episodes ID": "ed9454f4-e328-11ea-91a2-037bc920d6a0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_21_Niantic.mp3", + "Episodes Pubdate Date": "2019-06-21", + "Episodes Summary": "

Niantic is the company behind Pokemon Go, an augmented reality game where users walk around in the real world and catch Pokemon which appear on their screen.

The idea for augmented reality has existed for a long time. But the technology to bring augmented reality to the mass market has appeared only recently. Improved mobile technology makes it possible for a smartphone to display rendered 3-D images over a video stream without running out of battery.

Ingress was the first game to come out of Niantic, followed by Pokemon Go, but there are other games on the way. Niantic is also working on the Niantic Real World platform, a “planet-scale” AR platform that will allow independent developers to build multiplayer augmented reality experiences that are as dynamic and entertaining as Pokemon Go.

Paul Franceus is an engineer at Niantic, and he joins the show to describe his experience building and launching Pokemon Go, as well as abstracting the technology from Pokemon Go and opening up the Niantic Real World platform to developers.

Niantic developer contest finalists

", + "Episodes Title": "Niantic Real World with Paul Franceus", + "Episodes Uid": "SED4841234870", + "Episodes Audio File": "ff6c05fbd54ac4088d8f019d8c9b7146.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6l2", + "Episodes ID": "eb05cee8-e328-11ea-91a2-cf5e546616bf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_09_NoSQLRickHoulihan.mp3", + "Episodes Pubdate Date": "2020-01-09", + "Episodes Summary": "

NoSQL databases provide an interface for storing and accessing data that allows the user to work with data in an “unstructured” fashion. SQL databases require the data in the database to be “normalized,” meaning that each object in the entire database has an entry (or a null value) for each field. One advantage of NoSQL is that the different objects are “denormalized,” meaning that different objects in the database can have unique fields.

There is a widely held belief that NoSQL databases do not scale, or that there is some significant penalty that a developer will pay for using a NoSQL database as soon as their app becomes popular. The truth is much more subtle than that. 

NoSQL databases can perform as well as or better than SQL databases if the developers know the query patterns that their applications make. SQL databases will be a better choice in the condition where the database has a very wide spectrum of access patterns. But in many cases, an application has a narrow range of different requests for the database, and a NoSQL database can perform very well if the database is structured and optimized for these requests.

Rick Houlihan is an executive with Amazon Web Services who works with database teams and engineers to optimize their products and database infrastructure. Rick joins the show to discuss the tenets of NoSQL and describe the fundamental contrast between NoSQL and SQL database limitations.

", + "Episodes Title": "NoSQL Optimization with Rick Houlihan", + "Episodes Uid": "SED7876283496", + "Episodes Audio File": "cdbfab08eb5a3e2018160cc1e4cd322a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 2000, + "Episodes ID": "0c284e84-e329-11ea-91a2-bbcc8bda839f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/security_edited.mp3", + "Episodes Pubdate Date": "2017-01-04", + "Episodes Summary": "

Every digital system has vulnerabilities. Cars can be hacked, locked computers can be exploited, and credit cards can be spoofed. Security researchers make a career out of finding these types of vulnerabilities.

Samy Kamkar’s approach to security research is not just about dissection–it’s also about creativity. For many of the technologies he hacks on, Samy open-sources code that summarily describes the vulnerability he has been working on. For example, in his project PoisonTap, Samy open-sourced code that you can run on a $5 Raspberry Pi, and plug into a locked computer to exploit it.

Our conversation covered the art of deconstructing technologies for vulnerabilities and Samy’s goals as a security researcher. We also touched on some of the broader issues of modern security.

", + "Episodes Title": "Security Research with Samy Kamkar", + "Episodes Uid": "SED1873369904", + "Episodes Audio File": "4321619af83880fee0cf19eeb8e6efcf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "77a", + "Episodes ID": "e95024fe-e328-11ea-91a2-1b4981708029", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_15_AWSVirtualization.mp3", + "Episodes Pubdate Date": "2020-05-15", + "Episodes Summary": "

Amazon’s virtual server instances have come a long way since the early days of EC2. There are now a wide variety of available configuration options for spinning up an EC2 instance, which can be chosen from based on the workload that will be scheduled onto a virtual machine. There are also Fargate containers and AWS Lambda functions, creating even more options for someone who wants to deploy virtualized infrastructure.

The high demand for virtual machines has led to Amazon moving down the stack, designing custom hardware such as the Nitro security chip, and low level software such as the Firecracker virtual machine monitor. AWS also has built Outposts, which allow for on-prem usage of AWS infrastructure.

Anthony Liguori is an engineer at AWS who has worked on a range of virtualization infrastructure: software platforms, hypervisors, and hardware. Anthony joins the show to talk about virtualization at all levels of the stack.

", + "Episodes Title": "AWS Virtualization with Anthony Liguori", + "Episodes Uid": "SED2122910687", + "Episodes Audio File": "ea4b6a9cd2eb79a4fed2cbc3f67cfa07.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6cg", + "Episodes ID": "ebe91630-e328-11ea-91a2-a337337e80ae", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_22_HaseebCryptoStartups.mp3", + "Episodes Pubdate Date": "2019-10-22", + "Episodes Summary": "

Cryptocurrencies are a fundamental computer science invention. 

Cryptocurrencies crashed in 2018 but the technology remains as promising as ever. Bitcoin is a decentralized currency, and a plausible end state that is implied by Bitcoin’s current trajectory is a permissionless, decentralized financial system.

This idea of decentralized finance or “DeFi” begs numerous questions: who will build the companies that provide the infrastructure for decentralized finance? Who will be the lenders? Who will be the credit agencies? Who will be the escrow services? How big will the teams need to be? Will these systems be built on smart contracts, or can it be done with centralized cloud providers?

Haseeb Qureshi is a managing partner with DragonFly Capital and a frequent guest on SE Daily. He returns to the show to discuss his thesis on what kinds of crypto companies make sense, and how he thinks about investments into crypto startups. Haseeb recently wrote an article about how to build a crypto startup.

", + "Episodes Title": "Crypto Businesses with Haseeb Qureshi", + "Episodes Uid": "SED8175225199", + "Episodes Audio File": "d8b9ba19b282d35e85692feabb5541de.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 211, + "Episodes ID": "1ac611e2-e329-11ea-91a2-bb7680bf9ccc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Algorithmia_Edited.mp3", + "Episodes Pubdate Date": "2016-06-20", + "Episodes Summary": "

Algorithmia is marketplace for algorithms. A software engineer who writes an algorithm for image processing or spam detection or TF-IDF can turn that algorithm into a RESTful API to be consumed by other developers. Different algorithms can be composed together to build even higher level applications.

Diego Oppenheimer is the CEO of Algorithmia, and he joins the show today to explain how Algorithmia works. The company has developed its own container orchestration and management service, and operates similarly to the serverless computing paradigms that we have discussed on recent episodes of Software Engineering Daily. Diego also talks about the marketplace dynamics of building a platform for developers to sell algorithms to each other.

", + "Episodes Title": "Algorithm Marketplace with Diego Oppenheimer of Algorithmia", + "Episodes Uid": "SED5520719368", + "Episodes Audio File": "7b9cdbc8bff0f1b292107e5010717e5b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 289, + "Episodes ID": "12c584d2-e329-11ea-91a2-c3b72eac207a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/event_sourcing_edited.mp3", + "Episodes Pubdate Date": "2016-10-14", + "Episodes Summary": "

When a user of a social network updates her profile, that profile update needs to propagate to several databases that want to know about such an update–search indexes, user databases, caches, and other services. When Neha Narkhede was at LinkedIn, she helped develop Kafka, which was deployed at LinkedIn to help solve this very problem. Using Kafka as an event queue, LinkedIn adopted the CQRS architectural pattern together with event sourcing.

Event sourcing is an architectural pattern that allows changes to our application model to be represented as events. Each event is published to an event queue, and is pulled off of the queue by each of the various services that need to consume that event. Event sourcing and the related architectural pattern CQRS allow for a flow of information through an application that is easy to reason about, and has several other desirable properties.

In today’s episode, Neha explains how to use Kafka for event sourcing and how related software patterns are improving the architectures of companies like Netflix and Uber.

For more information, check out this Confluent blog entry.

", + "Episodes Title": "Kafka Event Sourcing with Neha Narkhede", + "Episodes Uid": "SED1344047057", + "Episodes Audio File": "5cb453ae8c73d287c994f0c034765191.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 679, + "Episodes ID": "ec63f30a-e328-11ea-91a2-778544e80b5c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_16_Okta.mp3", + "Episodes Pubdate Date": "2019-09-16", + "Episodes Summary": "

A new employee at a software company needs access to a variety of tools. In order to get started working, the employee might need Slack, email, Google Docs, and Amazon Web Services, and all of these require an account with a username and password.

Setting up all of these accounts can be time consuming, because the company needs to go into their admin portal and create the accounts. The accounts need to have the right security policies and configuration settings. And when the employee leaves the company, all of these accounts need to be shut down.

Okta is a company that builds identity and access management software, such as an “SSO (single-sign on)” tool that allows users to log into all of these different types of accounts using only an Okta login. Okta was started in 2009 and has grown steadily since then, going public in 2017.

Hector Aguilar is the president of technology at Okta and he joins the show to talk about the software stack of Okta and how the company has evolved over time as it has become a core infrastructure provider and hired a large engineering team.

", + "Episodes Title": "Okta Engineering with Hector Aguilar", + "Episodes Uid": "SED3748345609", + "Episodes Audio File": "407bf70cc0a00ecc5c1d53481bb75792.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6f0", + "Episodes ID": "eba2c9c8-e328-11ea-91a2-e75811e7d63a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_12_IncidentResponseML.mp3", + "Episodes Pubdate Date": "2019-11-12", + "Episodes Summary": "

Software bugs cause unexpected problems at every company. 

Some problems are small. A website goes down in the middle of the night, and the outage triggers a phone call to an engineer who has to wake up and fix the problem. Other problems can be significantly larger. When a major problem occurs, it can cause millions of dollars in losses and requires hours of work to fix.

When software unexpectedly breaks, it is called an incident. To triage these incidents, an engineer uses a combination of tools, including Slack, GitHub, cloud providers, and continuous deployment systems. These different tools emit updates that can be received by an incident response platform, which allow the on-call engineer to have the information they need centralized to more easily work through the incident.

On-call rotation means that different people will be responsible for dealing with different incidents that occur. When an incident happens, the current engineer who is on-call may not be aware that a similar incident happened last week. It might be easier for the new engineer to triage the issue if they have insights about how the incident was managed during the first time.

Chris Riley is a DevOps advocate with Splunk. He joins the show to discuss the application of machine learning to incident response. We discuss the different data points that are created during an incident, and how that data can be used to build models for different types of incidents, which can generate information to help the engineer respond appropriately to an incident. Full disclosure: Splunk is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Incident Response Machine Learning with Chris Riley", + "Episodes Uid": "SED5613275951", + "Episodes Audio File": "3363b1632ed6ccf2c58dc582053ce58b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1tg", + "Episodes ID": "1f9cba2c-e329-11ea-91a2-4faa024dfcb4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Alluxio_Edited.mp3", + "Episodes Pubdate Date": "2016-03-30", + "Episodes Summary": "

Memory is king. The cost of memory and disk capacity are both decreasing every year–but only the throughput of memory is increasing exponentially. This trend is driving opportunity in the space of big data processing.

Alluxio is an open source, memory-centric, distributed, and reliable storage system enabling data sharing across clusters at memory speed. Alluxio was formerly known as Tachyon. Haoyuan Li is the creator of Alluxio. Haoyuan was a member of the Berkeley AMPLab, which is the same research facility from which Apache Mesos and Apache Spark were born. In this episode, we discuss Alluxio, Spark, Hadoop, and the evolution of the data center software architecture.

", + "Episodes Title": "Alluxio and Memory-centric Distributed Storage with Haoyuan Li", + "Episodes Uid": "SED3539917340", + "Episodes Audio File": "008a52784793725d936a725f383b7027.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7gh", + "Episodes ID": "e864f678-e328-11ea-91a2-33a7c977c89d", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_23_Modin.mp3", + "Episodes Pubdate Date": "2020-07-23", + "Episodes Summary": "

Pandas is a Python data analysis library, and an essential tool in data science. Pandas allows users to load large quantities of data into a data structure called a dataframe, over which the user can call mathematical operations. When the data fits entirely into memory this works well, but sometimes there is too much data for a single box.

The Modin project scales Pandas workflows to multiple machines by utilizing Dask or Ray, which are distributed computing primitives for Python programs. Modin builds an execution plan for large data frames to be operated on against each other, which makes data science considerably easier for these large data sets.

Devin Petersohn started the Modin project, and he joins the show to talk about data science with Python, and his work in the Berkeley RISELab.

", + "Episodes Title": "Modin: Pandas Scalability with Devin Petersohn", + "Episodes Uid": "SED8499794430", + "Episodes Audio File": "6c7c04d9e30c92f6a8955ace5b6c2246.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2aj", + "Episodes ID": "1078a4a2-e329-11ea-91a2-8bcb4ce7b278", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/likefraud_edited.mp3", + "Episodes Pubdate Date": "2016-11-17", + "Episodes Summary": "

Botnets have a massive influence on the Internet. As we have seen recently with the Mirai Botnet, IOT bots can take down companies as big as Netflix. In our recent episodes about advertising fraud, we’ve talked about how bots are being used to take billions of dollars of revenue from advertisers.

Derek Muller is one of those advertisers who has spent money on ads and gotten nothing but fake traffic in return. Two years ago, he posted a video on YouTube about his experience purchasing advertising traffic on Facebook, and getting Likes from accounts that were clearly from fake accounts.

Derek is the host of Veritasium, an awesome YouTube channel about science, truth, and technology–so we also talked some about how he built a successful YouTube business.

", + "Episodes Title": "Botnet Facebook Likes with Derek Muller", + "Episodes Uid": "SED1446634332", + "Episodes Audio File": "1a3a35d9415287049318f63429aae1a0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "6b29505a-ecb0-11ea-9de8-23687810500f", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-03", + "Episodes Summary": "


", + "Episodes Title": "Modern Venture with Jerry Chen", + "Episodes Uid": "SED8033850464", + "Episodes Audio File": "4b6b97faa568e52c54db58e1de7744ed.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "70f", + "Episodes ID": "e9f6d0ec-e328-11ea-91a2-4b9956f75b81", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_30_PikaPackages.mp3", + "Episodes Pubdate Date": "2020-03-30", + "Episodes Summary": "

Modern web development involves a complicated toolchain for managing dependencies. One part of this toolchain is the bundler, a tool that puts all your code and dependencies together into static asset files. The most popular bundler is webpack, which was originally released in 2012, before browsers widely supported ES Modules.

Today, every major browser supports the ES Module system, which improves the efficiency of JavaScript dependency management. Snowpack is a system for managing dependencies that takes advantage of the browser support for ES Modules. Snowpack is made by Pika, a company that is developing a set of web technologies including a CDN, a package catalog, and a package code editor.

Fred Schott is the founder of Pika and the creator of Snowpack. Fred joins the show to talk about his goals with Pika, and the ways in which modern web development is changing.

", + "Episodes Title": "Pika Dependency Management with Fred Schott", + "Episodes Uid": "SED3521893221", + "Episodes Audio File": "844d50ad2996e51ae04d9001eaf521ee.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "79e", + "Episodes ID": "e925f576-e328-11ea-91a2-07ef259d9335", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_27_Brex.mp3", + "Episodes Pubdate Date": "2020-05-27", + "Episodes Summary": "

Brex is a credit card company that provides credit to startups, mostly companies which have raised money. Brex processes millions of transactions, and uses the data from those transactions to assess creditworthiness, prevent fraud, and surface insights for the users of their cards.

Brex is full of interesting engineering problems. The high volume of transactions requires data infrastructure to support all those transactions coming through the platform. As a credit card company, Brex needs to integrate with credit card networks and banking systems. There are internal systems for applications such as dispute resolution.

Cos Nicolaescu is the CTO at Brex. He joins the show to discuss engineering at Brex, the dynamics of a credit card company, and his strategies around management. It was an instructive look inside of a rapidly growing fintech company.

", + "Episodes Title": "Brex Engineering with Cosmin Nicolaescu", + "Episodes Uid": "SED4690395653", + "Episodes Audio File": "a36075540fcca0ad6f2dfd8db24e98f1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "66e", + "Episodes ID": "ec76388a-e328-11ea-91a2-a7e53d935716", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_10_SpannerDeepti.mp3", + "Episodes Pubdate Date": "2019-09-10", + "Episodes Summary": "

Spanner is a globally distributed, transactionally consistent database. 

Spanner initially emerged as a paper that came out of Google in 2012. Around this time, database scalability was difficult to solve, even for Google. The Spanner paper offered some breakthroughs in distributed systems which allowed Google to take some of the learnings from BigTable’s eventual consistency and construct a novel system that was transactionally consistent.

Deepti Srivastava has worked on Spanner for more than six years. When she initially started working on Spanner, she was involved in the internally facing Spanner system that Google engineers used to spin up instances of the database. Today, she works as program manager for Cloud Spanner, a product within Google Cloud. Deepti joins the show to describe the breakthroughs of Spanner, and how her work has evolved since the product has gone from an internal system to an externally facing piece of cloud infrastructure.

", + "Episodes Title": "Google Spanner with Deepti Srivastava", + "Episodes Uid": "SED2148905671", + "Episodes Audio File": "b5c94ee46e4d3b31e885d6bfd36c27e5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7it", + "Episodes ID": "e83a35d2-e328-11ea-91a2-cbfc7f140de5", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_19_SuperAnnotate.mp3", + "Episodes Pubdate Date": "2020-08-19", + "Episodes Summary": "

Image annotation is necessary for building supervised learning models for computer vision. An image annotation platform streamlines the annotation of these images. Well-known annotation platforms include Scale AI, Amazon Mechanical Turk, and Crowdflower.

There are also large consulting-like companies that will annotate images in bulk for you. If you have an application that requires lots of annotation, such as self-driving cars, then you might be compelled to outsource this annotation to such a company.

SuperAnnotate is an image annotation platform that can be used by these image annotation outsourcing firms. This episode explores SuperAnnotate, and the growing niche of image annotation. Vahan and Tigran Petrosyan are the founders of SuperAnnotate, and join the show for today’s interview.

", + "Episodes Title": "SuperAnnotate: Image Annotation Platform with Vahan and Tigran Petrosyan", + "Episodes Uid": "SED6638552328", + "Episodes Audio File": "21bbcac34f4c302c4a6e61000eb56ca4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2al", + "Episodes ID": "103cf470-e329-11ea-91a2-ef78bae6feeb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/kalzumeus_edited.mp3", + "Episodes Pubdate Date": "2016-11-18", + "Episodes Summary": "

Many programmers listening to this podcast are working at a big company, and they would prefer to be running their own software business. Patrick McKenzie has been writing about this topic for several years on his blog Kalzumeus.com. Almost a decade ago, he was working as an enterprise developer at a large company in Japan. Over time, his side projects started making enough money to justify his leaving to work on them full-time.

Starting a small successful software business is not about luck, or taking big risks, or having your muse deliver some brilliant insight. It is about studying the markets where you can build software that can deliver value. Patrick and I discuss this topic, as well as Stripe–where he now works today. He sold his small businesses to go work full time on Stripe Atlas, so his story of transitioning back to a big company is fascinating as well.

", + "Episodes Title": "Software Small Businesses with Patrick McKenzie", + "Episodes Uid": "SED9539653013", + "Episodes Audio File": "8b0cd32bc7d0918155fc60f1b895b7c0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6m5", + "Episodes ID": "eaea933a-e328-11ea-91a2-f7d60d9a0450", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_17_Apollo.mp3", + "Episodes Pubdate Date": "2020-01-17", + "Episodes Summary": "

GraphQL has become a core piece of infrastructure for many software applications. GraphQL is used to make requests that are structured as GraphQL queries and responded to through a GraphQL server. The GraphQL server processes the query and fetches the response from the necessary databases, APIs, and backend services.

Around 2016, when GraphQL was becoming popular, a company called Meteor was deciding what to do with its business. Meteor was started off of the popular framework MeteorJS, a system for building real-time JavaScript applications. MeteorJS was loved by many developers, but Meteor needed to decide if it was the most viable opportunity that it could be pursuing with its resources. 

From the vantage point within the Meteor company, there were some trends in the frontend ecosystem that were potentially disruptive to the viability of Meteor. There were also some large potential opportunities. The dramatic change to the frontend was largely coming as a downstream effect of Facebook’s open source technologies: React and GraphQL. Amidst these changes, Meteor shifted the company’s efforts entirely towards GraphQL and renamed the company Apollo. 

Geoff Schmidt is the CEO of Apollo, and he joins the show to talk about the GraphQL ecosystem, the business opportunities around GraphQL, and the process of pivoting from Meteor to Apollo.

If you are planning a hackathon, check out FindCollabs Hackathons. Whether you are running an internal hackathon for your company, or you are running an open hackathon so that users can try out your product, FindCollabs Hackathons are a tool for people to build projects and collaborate with each other. You can create your own hackathon   at FindCollabs.com.

", + "Episodes Title": "Apollo GraphQL with Geoff Schmidt", + "Episodes Uid": "SED4683693689", + "Episodes Audio File": "7e7bb5dd4fd3e9dd5cedc33ce5172319.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6d7", + "Episodes ID": "ebcd0bca-e328-11ea-91a2-f763bdf064c6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_30_FBBearCase.mp3", + "Episodes Pubdate Date": "2019-10-30", + "Episodes Summary": "

Facebook engineering is unique. Software is built at Facebook in a way that is distinctly different than any other company. In our series of shows about Facebook engineering, we have mostly covered the positive side of Facebook’s practices. In today’s show, we explore the downsides. 

Facebook moves fast. Engineers within the company must move fast, which can reduce the time spent on formal process and documentation. A fast pace can lead to a chaotic environment. In this kind of environment, not every employee thrives, and product development can sometimes suffer. But there are clear benefits to moving fast, and many software organizations could benefit from moving faster.

Pete Hunt was an engineer with Facebook who worked on Facebook Video, Instagram, and React. Nick Schrock worked on core infrastructure at Facebook and was the co-creator of GraphQL. Pete and Nick helped create the Facebook culture, and are aware of the best and worst aspects of it. They join the show to reflect on their time at Facebook, and the downsides of moving fast.

", + "Episodes Title": "Facebook Reflections with Pete Hunt and Nick Schrock", + "Episodes Uid": "SED3426540602", + "Episodes Audio File": "497867594a59aa961132198a88babf93.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 720, + "Episodes ID": "e9bb8bae-e328-11ea-91a2-1bd7c6a4c62f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_16_NGINXServiceMesh.mp3", + "Episodes Pubdate Date": "2020-04-16", + "Episodes Summary": "

NGINX is a web server that is used as a load balancer, an API gateway, a reverse proxy, and other purposes. Core application servers such as Ruby on Rails are often supported by NGINX, which handles routing the user requests between the different application server instances. 

This model of routing and load balancing between different application instances has matured over the last ten years due to an increase in the number of servers, and an increase in the variety of services. 

A pattern called “service mesh” has grown in popularity and is used to embed routing infrastructure closer to individual services by giving them a sidecar proxy. The application sidecars are connected to each other, and requests between any two services are routed through a proxy. These different proxies are managed by a central control plane which manages policies of the different proxies.

Alan Murphy works at NGINX, and he joins the show to give a brief history of NGINX and how the product has evolved from a reverse proxy and edge routing tool to a service mesh. Alan has worked in the world of load balancing and routing for more than a decade, having been at F5 Networks for many years before F5 acquired NGINX. We also discussed the business motivations behind the merger of those two companies. Full disclosure: NGINX is a sponsor of Software Engineering Daily.

", + "Episodes Title": "NGINX Service Mesh with Alan Murphy", + "Episodes Uid": "SED6366425734", + "Episodes Audio File": "d12059707934fe837e091121f2c2215b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24v", + "Episodes ID": "1700fa0e-e329-11ea-91a2-3f15a2a2983c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Flexport_Edited.mp3", + "Episodes Pubdate Date": "2016-08-15", + "Episodes Summary": "

Flexport is a technology company that makes logistics, supply chain management, and freight forwarding software. Shipping freight across the world requires container ships, airplanes, trains, warehouses, and trucks. Flexport’s software integrates with many of these different shipping companies, and provides a dashboard for the end user to understand how their products are being shipped around the world.
\nAmos Elliston is the CTO of Flexport, and he joins the show to discuss building software for the global supply chain.

", + "Episodes Title": "Flexport Engineering with Amos Elliston", + "Episodes Uid": "SED5622275652", + "Episodes Audio File": "33607d78ffd8cf8448b86e78bb12375a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1o9", + "Episodes ID": "21fc30f4-e329-11ea-91a2-a3878978ec4c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Codeship_Edited.mp3", + "Episodes Pubdate Date": "2016-03-01", + "Episodes Summary": "

Continuous integration and deployment are important tools for modern software development. With continuous integration and deployment, individual engineers can push code without waiting to synchronize with the rest of the team on a big software release.

Today on Software Engineering Daily, Flo Motlik, the CTO of Codeship, joins us to discuss continuous integration, dev ops, and microservices. In full disclosure, Codeship is a sponsor of Software Engineering Daily, but we would be doing this interview whether or not that was the case, because Flo has a lot to say about software engineering. In this show, we get into conversations and case studies of how software teams take continuous deployment from theory into practice.

", + "Episodes Title": "Continuous Delivery and Test Automation with Flo Motlik", + "Episodes Uid": "SED7959592655", + "Episodes Audio File": "0e9e4348bc7b8b2e7889be951b71733f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6bi", + "Episodes ID": "ec00e828-e328-11ea-91a2-effa6d1d38ee", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_15_Diffbot2.mp3", + "Episodes Pubdate Date": "2019-10-15", + "Episodes Summary": "

Diffbot is a knowledge graph that allows developers to interface with the unstructured web as if it was a structured database. In today’s show, Diffbot CEO Mike Tung returns for a second discussion about how he has built Diffbot and how Diffbot is used.

The web has many different entities. Web pages, topics, people, stories, articles, companies, and much more. Humans use a search engine to find answers to their questions within web pages. Machines need to find answers to these kinds of questions as well, but a machine is not sophisticated enough to figure out answers from an unstructured web page.

Diffbot brings structure to those webpages, and gives them an API interface for developers to build on top of. In order to create this system in a cost-efficient manner, Diffbot runs its own data centers, where web scraping, machine learning, and API infrastructure are all used to build the Diffbot application.

Mike joins me for an interview about creating Diffbot, as well as his strategy for running the business.

", + "Episodes Title": "Diffbot Infrastructure with Mike Tung", + "Episodes Uid": "SED1231259201", + "Episodes Audio File": "bb925dbe82661bd94674284b31112897.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2da", + "Episodes ID": "0dc75aa0-e329-11ea-91a2-a3f910fa3c9d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/hakkalabs_edited.mp3", + "Episodes Pubdate Date": "2016-12-21", + "Episodes Summary": "

In the last five years, companies started hiring data engineers. A data engineer creates the systems that manage and access the huge volumes of data that are accumulating on cheap cloud servers. As the saying goes, “it’s more expensive to throw out the data than to store it.”

Pete Soderling joins the show to discuss the rise of the data engineer, and how that role interacts with data scientists, software engineers, and machine learning experts. Pete runs Hakka Labs, a site that aggregates material for data science and data engineering. He also organizes DataEngConf, a conference for data engineering.

", + "Episodes Title": "Data Engineering with Pete Soderling", + "Episodes Uid": "SED7706081663", + "Episodes Audio File": "749df9d7f1fe6bfc6876bec5af12f044.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1sn", + "Episodes ID": "1fe37002-e329-11ea-91a2-0fe51d2a70a2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/devopstoptal_Edited.mp3", + "Episodes Pubdate Date": "2016-03-26", + "Episodes Summary": "

DevOps has been the subject of many episodes of Software Engineering Daily. And yet–the question we continue to ask ourselves is “what is DevOps?” In order to understand the present, we must look into the past. On today’s show, we break down the history of dev ops with Demir Selmanovic, the lead technical editor at TopTal.

From waterfall software development, to the agile manifesto. From lean manufacturing to the productive pinnacle of DevOps nirvana. Demir also wrote a blog post called What the Hell is DevOps, which he posted on the TopTal blog. Full disclosure: TopTal is a sponsor of our show, but this episode doesn’t discuss TopTal very much so hopefully that doesn’t impact the trust of our listeners.

", + "Episodes Title": "DevOps at TopTal with Demir Selmanovic", + "Episodes Uid": "SED6833579968", + "Episodes Audio File": "eb8dd05393d26dfdccabb45c0899205e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "66h", + "Episodes ID": "ec686cc8-e328-11ea-91a2-dbc3a6daa3b6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_13_CloudNativeCornelia.mp3", + "Episodes Pubdate Date": "2019-09-13", + "Episodes Summary": "

Amazon Web Services first came out in 2006.

It took several years before the software industry realized that cloud computing was a transformative piece of technology. Initially, the common perspective around cloud computing was that it was a useful tool for startups, but would not be a smart option for large, established businesses. Cloud computing was not considered economical nor secure.

Today, that has changed. Every company that writes software is figuring out how to utilize the cloud. Software companies with on-prem servers are migrating old applications to the cloud, and most companies that have started in the last decade do not even have physical servers. 

Applications that are started on the cloud are referred to as “cloud-native.” The architecture of cloud-native applications is a newer topic of discussion, and some software patterns that became established in the pre-cloud era make less sense today.

Cornelia Davis is VP of technology at Pivotal and the author of Cloud Native Patterns, a book about developing applications in the distributed, virtual world of the cloud. Cornelia was previously on the show to discuss Cloud Foundry. In today’s episode, our conversation centers on her book, and her perspective on the emerging patterns of cloud native software.

", + "Episodes Title": "Cloud-Native Applications with Cornelia Davis", + "Episodes Uid": "SED8326741484", + "Episodes Audio File": "4dce595e76475dadb214b675a7e369dd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "70n", + "Episodes ID": "e9ed7fce-e328-11ea-91a2-1f4ca3c99e53", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_01_AudioDataEngineering.mp3", + "Episodes Pubdate Date": "2020-04-01", + "Episodes Summary": "

Cortico is a non-profit that builds audio tools to improve public dialogue. Allison King is an engineer at Cortico, and she joins the show to talk about the process of building audio applications. 

One of these applications was a system for ingesting radio streams, transcribing the radio, and looking for duplicate information across the different radio stations. In a talk at Data Council, Allison talked through the data engineering architecture for processing these radio streams, and the patterns that she found across the radio streams, including clusters of political leanings.

Another project from Cortico is called Local Voices Network. The Local Voices Network is built around a piece of hardware called a “digital hearth”, a specialized device that records discussions among people in a community. These community discussions are made available to journalists, public officials, and political candidates, creating a listening channel that connects these communities and stakeholders. Much of our conversation is focused on the engineering of the digital hearth, this device that sits in the center of community discussions.

", + "Episodes Title": "Audio Data Engineering with Allison King", + "Episodes Uid": "SED3745995662", + "Episodes Audio File": "9f524fc3c8236801e62cd4ca2943efff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "70k", + "Episodes ID": "e9f21200-e328-11ea-91a2-676fda50c18e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_31_FacebookMessengerEngineering.mp3", + "Episodes Pubdate Date": "2020-03-31", + "Episodes Summary": "

Facebook Messenger is a chat application that millions of people use every day to talk to each other. Over time, Messenger has grown to include group chats, video chats, animations, facial filters, stories, and many more features. Messenger is a tool for utility as well as for entertainment.

Messenger is used both on mobile and on desktop, but the size of the mobile application is particularly important on mobile. There are many users who are on devices that do not have much storage space.

As Messenger has accumulated features, the iOS code base has grown larger and larger. Several generations of Facebook engineers have rotated through the company with the responsibility of working on Facebook Messenger, which has led to different ways of managing information within the same codebase. The iOS codebase had room for improvement.

Project Lightspeed was a project within Facebook that had the goal of making Messenger on iOS much smaller. Mohsen Agsen is an engineer with Facebook, and he joins the show to talk about the process of rewriting the Messenger app.

", + "Episodes Title": "Facebook Messenger Engineering with Mohsen Agsen", + "Episodes Uid": "SED6385938252", + "Episodes Audio File": "803ce4619feab3f0443fc80c2a9de93c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7fm", + "Episodes ID": "e87cf020-e328-11ea-91a2-9bba0b5069ce", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_16_Captec.mp3", + "Episodes Pubdate Date": "2020-07-16", + "Episodes Summary": "

Software companies can be funded in a variety of ways: venture capital, self-funding, and debt, among others. In order to receive financing, a company is evaluated on its ability to generate future cash flows. After all, a valuation is a number that summarizes the present value of future cash flows.

Determining that valuation number is a complicated, subjective process. If the valuation can be determined more intelligently and objectively, then smarter financing decisions can be made. This is the reasoning behind the company Capital, which aims to build a better modeling system for evaluating companies.

Blair Silverberg and Chris Olivares are founders of Capital, and they join the show to explore the modeling process for valuations, and their strategy for doing this with their software models.

", + "Episodes Title": "Capital Allocation with Blair Silverberg and Chris Olivares", + "Episodes Uid": "SED9594644076", + "Episodes Audio File": "a36ed0d58fe715bf8b718f5b6d51343e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5hz", + "Episodes ID": "eed11758-e328-11ea-91a2-8f0caf09d17f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_25_CodeSandbox.mp3", + "Episodes Pubdate Date": "2019-03-25", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Coding in the browser has been attempted several times in the last decade. Building a development environment in the browser has numerous technical challenges. How does the code execute safely? How do you fit all of the requirements of a development environment into a browser window? How do you get users to switch from their normal IDE (interactive development environment)?

CodeSandbox is an online code editor created by Ives van Hoorne and Bas Buursma. CodeSandbox allows users to program and run applications in the browser. It is a full developer platform that allows users the ability to install npm modules, run their code, and share their applications with other users.

The engineering problems within CodeSandbox are not easy–building a web-based IDE is complicated. But CodeSandbox is also an exciting project because it lowers the barrier to entry for many newer programmers. The development experience for a new programmer is still a difficult onramp.

If you are an experienced developer, you have a workflow that you are comfortable with. It might involve vim, or emacs, or JetBrains IDEs, or Eclipse. But newer developers can find these environments confusing and hard to get started with. The development environments of today are integrated with build tools, Github repositories, and deployment platforms. This can be overwhelming for a newer developer.

CodeSandbox is a very visual tool, which makes it especially useful for new developers who learn through seeing examples running live in the browser. CodeSandbox is also used by web developers who want a modern, shareable form of developing software.

Ives and Bas join the show to talk about the motivation for CodeSandbox and the engineering challenges they have solved.

", + "Episodes Title": "CodeSandbox: Online Code Editor with Bas Buursma and Ives van Hoorne", + "Episodes Uid": "SED1962102950", + "Episodes Audio File": "6b9652fe63369857014732507d083eea.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6h9", + "Episodes ID": "eb5d72ec-e328-11ea-91a2-77974a1d873c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_02_DistributedSQL.mp3", + "Episodes Pubdate Date": "2019-12-02", + "Episodes Summary": "

Relational databases provide durable transactional systems for storing data. The relational model has existed for decades, but the requirements for a relational database have changed.

Modern applications have requirements for high volumes of data that do not fit onto a single machine. When a database gets too big to fit on a single machine, that database needs to be sharded into smaller subsets of the data. These database shards are spread across multiple machines, and as the database grows, the database can be resharded to scale to even more machines.

To ensure durability, a database needs to be replicated. The database needs to be able to survive any single machine losing power or getting destroyed.

Sharding and replication allow a relational database to be scalable, durable, and highly available. There are many ways to build sharding and replication into a database. Karthik Ranganathan and Sidharth Choudhury are engineers with YugabyteDB, a distributed SQL database.

In today’s episode, we discuss the modern requirements of a distributed SQL database, and compare the applications of distributed SQL to those of other systems such as Cassandra and Hadoop. We also talk through the competitive market of cloud-based distributed SQL providers such as Google Cloud Spanner and Amazon Aurora. YugabyteDB is an open source database that competes with these other relational databases. Full disclosure: YugabyteDB is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Distributed SQL with Karthik Ranganathan and Sidharth Choudhury", + "Episodes Uid": "SED7820278047", + "Episodes Audio File": "d27190df083ce846545634c4a9c2e140.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6do", + "Episodes ID": "ebbd9f6e-e328-11ea-91a2-036a742209b0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_04_LeadershipwithBenHorowitz.mp3", + "Episodes Pubdate Date": "2019-11-04", + "Episodes Summary": "

Photo credit: Elisabeth Fall

Ben Horowitz started Loudcloud with Marc Andreessen in 1999. He ran the company for eight years and chronicled his experience in his first book The Hard Thing About Hard Things.

In his time running Loudcloud, the dotcom bubble burst, but Loudcloud needed cash so badly that he took the company public in 2001. Loudcloud went through layoffs, downsizing, and a difficult strategic maneuver in which Loudcloud sold its cloud provider business for cash, then used the core competency it had developed to create new software for building and running cloud services. This new software was the core product of the company Opsware, which was sold to HP in 2007 for $1.6bn.

The Loudcloud story looks like a rational, straightforward execution in retrospect, but at many points in the timeline, Ben was unsure he was making the correct decision. As the subtitle of his first book states “there are no easy answers.” 

The Hard Thing About Hard Things tells the story of Loudcloud and Opsware in harrowing detail. Most founders of software companies will end up reading the book at some point when they are building their company, because there are so few books which capture the granular details of what it feels like to run a company.

A CEO is completely alone in their understanding of the company. Nobody else has nearly as much information as the CEO–not the board, not the market, and not the employees. When you are a CEO, there is simply nobody to turn to who can give you the actionable advice that you wish you could have access to. And because there is nobody else, it means that the CEO’s own psychological state is extremely important.

The Hard Thing About Hard Things provides a CEO with solace: while the CEO is alone within their company, they are not alone in the world. Every CEO has a set of issues which they have never faced before, and the CEO can learn to face those issues confidently and competently. 

Like any influential book, The Hard Thing About Hard Things presents the reader with useful answers, but also raises many questions. How can a normal person foster the mentality of a leader? How can a leader convince smart people to follow their direction? How can a seemingly crazy direction be framed as completely rational?

The second book by Ben Horowitz is called What You Do Is Who You Are. This book surveys a set of case studies in leadership, including a Haitian slave revolt, the Mongol empire, and a dominant prison gang. By studying violent environments, Ben frames leadership in the context of the highest stakes. 

These stories are about life and death. When a leader’s performance is measured in blood, it frames the true nature of leadership in the starkest resolution. Ben uses each distilled example as a base case which inducts into broader applications: the cultures of Netflix, Facebook, Uber, and McDonalds are explored alongside editorials about Hillary Clinton and hip hop culture.

Throughout all of these stories, the most important thread is continually reinforced: the leader creates the culture. The culture is the leader. What you do is who you are.

Ben joins the show to discuss his writing, and how he has applied these beliefs to Andreessen Horowitz, the venture capital firm he co-founded and leads today.

", + "Episodes Title": "Leadership with Ben Horowitz", + "Episodes Uid": "SED9956999310", + "Episodes Audio File": "fcdd0857fe7a5fec0255a04ad28677ab.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1q5", + "Episodes ID": "20e6db6a-e329-11ea-91a2-271d47efe2a7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Mapping_Edited.mp3", + "Episodes Pubdate Date": "2016-03-14", + "Episodes Summary": "

On Software Engineering Daily, we often discuss big data in terms of data engineering and data science. Data engineering is the infrastructure and pipelines that handle massive amounts of data and puts that data in a data lake. With a data infrastructure in place, a data scientist can study the data and take action on it. A data scientist can also create visualizations–which is the subject of today’s episode.

Aurelia Moser has a specialty in mapping and data visualization. We discussed how to create effective visualizations of our data, and the tools that can be used to collect and present our data. Whether you work at the New York Times or a small tech company, data visualizations are important, because visualizations can be used to communicate important trends across an organization. Aurelia will also be speaking at the upcoming Strata + Hadoop World Conference in San Jose. We’re partnering with O’Reilly to support this conference – if you want to go to Strata, you can save 20% off a ticket with our code PCSED.

", + "Episodes Title": "Data Visualization and Mapping with Aurelia Moser", + "Episodes Uid": "SED2626766686", + "Episodes Audio File": "e5fa91cdaf304257ebca9e0dbbb7e5fe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 284, + "Episodes ID": "12ec4248-e329-11ea-91a2-d72c9a04fc70", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/scheduling_at_netflix_edited.mp3", + "Episodes Pubdate Date": "2016-10-12", + "Episodes Summary": "

At Netflix, developers write applications with a variety of requirements–from simple requests for a list of movies to more resource-intensive requests like a complex machine learning workflow. Netflix wants developers to be able to request the resources they need from a compute cluster and receive those resources on-demand, without thinking too much about the state of that pool of resources they are drawing from.

At the cluster level, this means scheduling the application requests intelligently. Sharma Podila, a distributed systems software architect at Netflix, explains how Netflix has built a cloud native scheduling system on top of Mesos.

", + "Episodes Title": "Netflix Scheduling with Sharma Podila", + "Episodes Uid": "SED3732238962", + "Episodes Audio File": "687fdd20889677a2bf66ea384021c993.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "79g", + "Episodes ID": "e91d065a-e328-11ea-91a2-03fddb37b7dd", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_29_KubevsServerless.mp3", + "Episodes Pubdate Date": "2020-05-29", + "Episodes Summary": "

Kubernetes has become a highly usable platform for deploying and managing distributed systems. 

The user experience for Kubernetes is great, but is still not as simple as a full-on serverless implementation–at least, that has been a long-held assumption. Why would you manage your own infrastructure, even if it is Kubernetes? Why not use autoscaling Lambda functions and other infrastructure-as-a-service products?

Matt Ward is a listener of the show and an engineer at Mux, a company that makes video streaming APIs. He sent me an email that said Mux has been having success with self-managed Kubernetes infrastructure, which they deliberately opted for over a serverless deployment. I wanted to know more about what shaped this decision to opt for self-managed infrastructure, and the costs and benefits that Mux has accrued as a result.

Matt joins the show to talk through his work at Mux, and the architectural impact of opting for Kubernetes instead of fully managed serverless infrastructure.

", + "Episodes Title": "Kubernetes vs. Serverless with Matt Ward", + "Episodes Uid": "SED8943952265", + "Episodes Audio File": "e6b4ded2a52caf580b579ff3cb2c403f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7cw", + "Episodes ID": "e8c3b834-e328-11ea-91a2-43202080f85d", + "Episodes Original URL": "https://sd-profile-pictures.s3-us-west-2.amazonaws.com/adfree/2019_10_08_Traces_adfree.mp3", + "Episodes Pubdate Date": "2020-06-25", + "Episodes Summary": "

Originally published October 8, 2019. We are taking a few weeks off. We’ll be back soon with new episodes.

Video surveillance impacts human lives every day. 

On most days, we do not feel the impact of video surveillance. But the effects of video surveillance have tremendous potential. It can be used to solve crimes and find missing children. It can be used to intimidate journalists and empower dictators. Like any piece of technology, video surveillance can be used for good or evil.

Video recognition lets us make better use of video feeds. A stream of raw video doesn’t provide much utility if we can’t easily model its contents. Without video recognition, we must have a human sitting in front of the video to manually understand what is going on in that video.

Veronica Yurchuk and Kosh Shysh are the founders of Traces.ai, a company building video recognition technology focused on safety, anonymity, and positive usage. They join the show to discuss the field of video analysis, and their vision for how video will shape our lives in the future.

", + "Episodes Title": "Traces: Video Recognition with Veronica Yurchuk and Kostyantyn Shysh (Summer Break Repeat)", + "Episodes Uid": "SED1250128568", + "Episodes Audio File": "9ece3ea48f4274102f441d01ee9eae7b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6qb", + "Episodes ID": "eaa9aa82-e328-11ea-91a2-1b6c93ce930b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_06_NubankDataPlatform.mp3", + "Episodes Pubdate Date": "2020-02-06", + "Episodes Summary": "

Nubank is a popular bank that is based in Brazil. Nubank has more than 20 million customers, and has accumulated a high volume of data over the six years since it was started.

Mobile computing and cloud computing have given rise to “challenger banks” that operate more like software companies. When a software company reaches the size that Nubank is at today, it needs a data platform.

A data platform is a collection of different technologies that move data into different storage formats and applications, so that different members of an organization can access that data. New data often enters an organization through an OLTP database, which supports user transactions. That data is copied into a data lake, which provides cheap bulk storage. From the data lake, the data is moved into a data warehouse system for fast access. Along the way, tools like Kafka, Spark, and S3 are used to implement the needs of the data platform.

Data platform architecture is not an exact science. Different companies build their data platform based on their own unique requirements. Previous shows have covered the data infrastructure companies like Lyft, Uber, and Facebook. Today’s show is another case study in data infrastructure, with a modern bank.

In a previous episode, we covered the engineering of Nubank. Sujith Nair from Nubank joins today’s show to talk about the data infrastructure of the company. 

If you enjoy the show, you can find all of our past episodes about data infrastructure by going to SoftwareDaily.com and searching for the technologies or companies mentioned. And if there is a subject that you want to hear covered, feel free to leave a comment on the episode, or send us a tweet @software_daily.

", + "Episodes Title": "Nubank Data Engineering with Sujith Nair", + "Episodes Uid": "SED5555695343", + "Episodes Audio File": "c092f1e0114a84f90920d041c0433b77.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2de", + "Episodes ID": "0d6a62d2-e329-11ea-91a2-dfc2243a8f0e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/antifraud_architecture_edited.mp3", + "Episodes Pubdate Date": "2016-12-23", + "Episodes Summary": "

Online marketplaces and social networks often have a trust and safety team. The trust and safety team helps protect the platform from scams, fraud, and malicious actors. To detect these bad actors at scale requires building a system that classifies every transaction on the platform as safe or potentially malicious.

Since every social platform has to build something like this, Smyte decided to engineer trust and safety as a service. Josh Yudaken joins the show today to discuss how Smyte engineered its platform to provide machine learning models for any organization that wants to take advantage of Smyte for its trust and safety.

The tools we discuss include Kubernetes, RocksDB, and Kafka, and Smyte is solving some problems that have not been solved before, so this is a great episode for anyone interested in data engineering or fraud detection–or how to use cloud services and open source tools in unique ways.

", + "Episodes Title": "Antifraud Architecture with Josh Yudaken", + "Episodes Uid": "SED8559338103", + "Episodes Audio File": "a2c0b24515414ac6c45f81f158e8b9da.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "68b", + "Episodes ID": "ec3cee04-e328-11ea-91a2-5fce5ffc9fe6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_26_EthosLifeInsurance.mp3", + "Episodes Pubdate Date": "2019-09-26", + "Episodes Summary": "

Ethos Life Insurance is a software company that sells life insurance products.

Software is reshaping established industries such as banking, insurance, and manufacturing. In these large, established industries, incumbents are adopting new technology as fast as they can, but the new technology needs to be integrated with the old technology. The slow rate of technology adoption by incumbents creates an opportunity for new companies to spring up who are building their entire company from scratch, with updated software.

Insurance is a gigantic market that is dominated by companies which have been around for 50-100 years. The established players in the insurance industry are trusted brands, but many of them have not significantly updated their technology from legacy techniques of pricing risk.

Vipul Sharma is the VP of engineering and Lingke Wang is the co-founder of Ethos Life Insurance, and they join the show to describe the insurance business, the technical problems, and the software stack of modern insurance company. Ethos has more than fifty employees and is growing rapidly, so it is a great case study in scaling a modern company in an established market.

", + "Episodes Title": "Life Insurance Engineering with Vipul Sharma and Lingke Wang", + "Episodes Uid": "SED9634519902", + "Episodes Audio File": "dc0a138587d4801934b26b5f0a802e66.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25d", + "Episodes ID": "159fb2ea-e329-11ea-91a2-0391e2e4750a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Bachbot_Edited.mp3", + "Episodes Pubdate Date": "2016-09-02", + "Episodes Summary": "

Machine learning can be used to generate music. In the case of Feynman Liang’s research project BachBot, the machine learning model is seeded with the music of famous composer Bach. The music that BachBot creates sounds remarkably similar to Bach, although it has been generated by an algorithm, not by a human.

BachBot is a research project on computational creativity. Feynman Liang created BachBot using Python machine learning tools to build a long-short term memory model. Our conversation explores artificial intelligence, music, and his approach to this research project.

", + "Episodes Title": "Music Deep Learning with Feynman Liang", + "Episodes Uid": "SED6249651325", + "Episodes Audio File": "1f943ded5b50e473f31ef4742ba969fc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 279, + "Episodes ID": "1416d16a-e329-11ea-91a2-439b48185a21", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Container_Edited.mp3", + "Episodes Pubdate Date": "2016-09-26", + "Episodes Summary": "

Containers have become the unit of infrastructure that many technology stacks deploy to. With the shift to containers, the attack surface of an application has changed, and we need to reconsider our security models; the resource allocation of our containers, the interactions between different containers on a single machine, and the big picture–how the external web may interact with our containers.
\nPhil Estes joins the show to discuss container security, as well as the OCI, container orchestration, as well as other container related topics.

", + "Episodes Title": "Container Security with Phil Estes", + "Episodes Uid": "SED7367702961", + "Episodes Audio File": "1aaeac5c47c8db53236a30fc6ada2248.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ps", + "Episodes ID": "eab35320-e328-11ea-91a2-bbe687ba34cb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_04_Rive2DimensionAnimation.mp3", + "Episodes Pubdate Date": "2020-02-04", + "Episodes Summary": "

Animations can be used to create games, app tutorials, and user interface components. Animations can be seen in messaging apps, where animated reactions can convey rich feelings over a text interface. Loading screens can become less boring through animation, and voice assistant products can feel more alive through animation.

But we still don’t see much animation in our everyday applications. This is partly because animation tooling is difficult to use. To make an animation, the typical workflow is to go into a tool like After Effects, render your animation, and then export that animation in a movie format. This format is not dynamic enough to be easily used on the wide variety of development platforms.

The animation library Lottie did improve this tooling by creating a system for exporting animations to JSON and allowing them to easily scale up and down as vectors. But the animations still were simple and unidirectional. The developer did not have much freedom for how to move an animation in response to user input.

Rive is a system for creating dynamic, movable animated objects. Rive allows for the creation of animated elements that respond to user input. Rive has a tool that runs in the browser and allows the user to define the animation. 

The animations in Rive use a bone system that allows animators and designers to define the points of the animated sprite that the developer can then manipulate with code. This improves the painful handoff process that exists between animators and developers, and gives the developer some programmatic control.

Guido and Luigi Rosso are the founders of Rive and they join the show to talk about the frictions of animation tooling, and what they have built to improve

", + "Episodes Title": "Rive: Animation Tooling with Guido and Luigi Rosso", + "Episodes Uid": "SED7591342977", + "Episodes Audio File": "93252b0b12721ead74656faea9f61e90.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1om", + "Episodes ID": "21ade7b4-e329-11ea-91a2-d7ebc2cf0c38", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/geekwire_Edited.mp3", + "Episodes Pubdate Date": "2016-03-05", + "Episodes Summary": "

Microsoft and Amazon are the tech giants of the Pacific Northwest. These two companies shape Seattle technology, and Todd Bishop has been writing about them for over a decade. Todd is the co-founder of GeekWire, an online media company focused on technology in the Pacific Northwest. We talk about the past and present of Microsoft and Amazon, what it means for an engineering company to be good or evil, and what it’s like to be a software journalist.

", + "Episodes Title": "Software Journalism at GeekWire with Todd Bishop", + "Episodes Uid": "SED9196139665", + "Episodes Audio File": "16bf31f394d20c4b9deb727fa5b570ce.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1wg", + "Episodes ID": "1e7b8100-e329-11ea-91a2-830d8448df98", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Algolia_Edited_2.mp3", + "Episodes Pubdate Date": "2016-04-18", + "Episodes Summary": "

Engineers who want to add search to their application usually deploy Elasticsearch, or write their own search engine that uses TF-IDF. These solutions work well for large documents, but are less effective for large volumes of small records–which is how many modern web and mobile applications are structured.

In today’s show, Julien Lemoine discusses how his company Algolia thinks about search. Algolia is a search as a service company that gives developers an easier way to search on their websites and applications.

", + "Episodes Title": "Search as a Service with Julien Lemoine", + "Episodes Uid": "SED2919704159", + "Episodes Audio File": "893aa3be40c9aab9a00c9a8f49e945ea.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 287, + "Episodes ID": "12d56d66-e329-11ea-91a2-eba271132a5c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/devops_handbook_edited.mp3", + "Episodes Pubdate Date": "2016-10-13", + "Episodes Summary": "

The intent of the DevOps movement is to get organizations moving faster and more effectively by breaking down siloes, and improving communication. Gene Kim’s book The Phoenix Project illustrated this by telling the fictional story of a company adopting a DevOps mentality. Although that book was fiction, Gene is an experienced engineer, having worked as founder and CTO of Tripwire, a software company that makes security and compliance automation software.

In his new book The DevOps Handbook, Gene presents a practical companion to The Phoenix Project. Together with his co-authors, Gene has written a guide for how to move an organization toward DevOps, and in this episode we explore some of the topics from his book.

Check out an excerpt from Gene’s book here: DevOps Handbook

", + "Episodes Title": "DevOps Handbook with Gene Kim", + "Episodes Uid": "SED4581066574", + "Episodes Audio File": "396418474f5062d1298c51589893b66a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24s", + "Episodes ID": "17216eba-e329-11ea-91a2-7f470fcb6e63", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Troy_Hunt_Edited_2.mp3", + "Episodes Pubdate Date": "2016-08-12", + "Episodes Summary": "

When you hear about massive data breaches like the recent ones from LinkedIn, MySpace, or Ashley Madison, how can you find out whether your own data was compromised?

Troy Hunt created the website HaveIBeenPwned.com to answer this question. When a major data breach occurs, Troy acquires a copy of the stolen data and provides a safe way for individuals to check if their credentials have been stolen.
\nTroy is an expert on data breaches, and he works as a regional director at Microsoft. Our conversation explores passwords, IoT security, Stuxnet, and the dark, bizarre world of data breaches.

", + "Episodes Title": "Data Breaches with Troy Hunt", + "Episodes Uid": "SED5318160701", + "Episodes Audio File": "eb966083f8027b4a41c3a348bcb0bc06.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ae", + "Episodes ID": "e90ac454-e328-11ea-91a2-b7b62a29941e", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_04_Prisma.mp3", + "Episodes Pubdate Date": "2020-06-04", + "Episodes Summary": "

A frontend developer issuing a query to a backend server typically requires the developer to issue that query through an ORM or a raw database query. Prisma is an alternative to both of these data access patterns, allowing for easier database access through auto-generated, type-safe query building tailored to an existing database schema.

By integrating with Prisma, the developer gets a database client that has query autocompletion, and an API server with less boilerplate code. Prisma also has a system called Prisma Migrate, which simplifies database and schema migrations.

Johannes Schickling is CEO of Prisma, and he joins the show to talk about the developments of Prisma that have occurred since we last spoke, and where the company is headed.

", + "Episodes Title": "Prisma: Modern Database Tooling with Johannes Schickling", + "Episodes Uid": "SED6851957149", + "Episodes Audio File": "a85221ae1b44b9d19bb6cbad7eff927a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7eo", + "Episodes ID": "e899d6fe-e328-11ea-91a2-3f39c27f1a6b", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_08_Determined.mp3", + "Episodes Pubdate Date": "2020-07-08", + "Episodes Summary": "

Developing machine learning models is not easy. From the perspective of the machine learning researcher, there is the iterative process of tuning hyperparameters and selecting relevant features. From the perspective of the operations engineer, there is a handoff from development to production, and the management of GPU clusters to parallelize model training.

In the last five years, machine learning has become easier to use thanks to point solutions. TensorFlow, cloud provider tools, Spark, Jupyter Notebooks. But every company works differently, and there are few hard and fast rules for the workflows around machine learning operations.

Determined AI is a platform that provides a means for collaborating around data prep, model development and training, and model deployment. Neil Conway is a co-founder of Determined, and he joins the show to discuss the challenges around machine learning operations, and what he has built with Determined.

", + "Episodes Title": "Determined AI: Machine Learning Ops with Neil Conway", + "Episodes Uid": "SED4819079154", + "Episodes Audio File": "60c51c06020d75413d3e94c46b432c75.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ls", + "Episodes ID": "eaf3912e-e328-11ea-91a2-7f60f2c0a90e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_15_PacketInfrastructure.mp3", + "Episodes Pubdate Date": "2020-01-15", + "Episodes Summary": "

Cloud infrastructure is usually consumed in the form of virtual machines or containers. These VMs or containers are running on a physical host machine that is also running other VMs and containers. This is called multitenancy. Servers across cloud providers such as AWS have a high utilization because there are multiple virtual instances running on each physical server host.

Cloud computing has led to a low cost of compute infrastructure. But in some cases, this low cost comes at the price of not being able to control the underlying hardware with as much precision as the user would want. Some users want specific types of hardware. Other users want to be using dedicated hardware that does not risk the “noisy neighbor” problem of sharing a physical server with some other application that is using most of the resources.

Packet is a company that provides remote access to baremetal infrastructure. The user experience is similar to that of a cloud provider, but with more control over how a given physical host will be used. Zachary Smith is the CEO of Packet and Nathan Goulding is the chief architect. Zach and Nathan join the show to talk about the business and the engineering behind Packet, as well as the future goals for where they want to take the company.

", + "Episodes Title": "Packet: Baremetal Infrastructure with Zachary Smith and Nathan Goulding", + "Episodes Uid": "SED9046156377", + "Episodes Audio File": "37c4e779370b6b8c259f740423b2b500.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6po", + "Episodes ID": "eab7bc6c-e328-11ea-91a2-6303c624aad7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/John_Deere_Engineering.mp3", + "Episodes Pubdate Date": "2020-02-03", + "Episodes Summary": "

Robotics has changed modern agriculture. Autonomous systems are powering the tractors, cotton pickers, and corn cutters that yield plants at industrial scale.

John Deere is a company that has been making farm equipment for 183 years. Over that period, the planting and harvesting process has become increasingly mechanized, and John Deere has been at the forefront. Over the last few decades, software has played an increasingly important role at John Deere.

Today, there is software inside the vehicles. These vehicles can operate autonomously, they collect large amounts of data, and they are supported by a large system of cloud services. The teams within John Deere who create the software have an elaborate testing workflow that allows them to deploy the software to the vehicles and drive them in the field.

Ryan Bergman is a software engineer at John Deere and he joins the show to talk about the software engineering, management, and DevOps practices within the company. 

", + "Episodes Title": "John Deere: Farm Software with Ryan Bergman", + "Episodes Uid": "SED2207329944", + "Episodes Audio File": "be26105bcb0b989a3fbed1eca6e561e0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6v7", + "Episodes ID": "ea6811a8-e328-11ea-91a2-f384672c0520", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_25_DecentralizedExchanges.mp3", + "Episodes Pubdate Date": "2020-02-25", + "Episodes Summary": "

Cryptocurrencies today serve two purposes: store of value and speculation. 

The application infrastructure that has been built around cryptocurrency is mostly to support these use cases. At some point in the future, perhaps cryptocurrencies can be used as a global medium of exchange that is accepted at the grocery store. Perhaps we will use the blockchain for supply chain management, and as a universal ledger for real estate ownership.

But today, cryptocurrencies are mostly used for speculative trading. Users buy and sell different cryptocurrencies and stablecoins, looking to make short-term profits. And the markets for trading cryptocurrencies have evolved to have a sophistication that looks like the centralized markets of derivatives and leverage-based day trading.

The term “decentralized finance” refers to this phenomenon of cryptocurrency lending markets. Decentralized finance increases the volume of speculated capital by providing liquidity through smart contracts. This short-term liquidity is often collateralized by a volatile cryptocurrency such as Ethereum, creating an opportunity for a type of market participant called a “liquidator.”

Tom Schmidt is an investor with Dragonfly Capital, a cryptoasset investment firm. Tom joins the show to describe the dynamics of decentralized finance.

", + "Episodes Title": "Decentralized Finance with Tom Schmidt", + "Episodes Uid": "SED7507066582", + "Episodes Audio File": "fbcbe27ec66e211c5bf30f2a921f9581.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1vv", + "Episodes ID": "1ea421be-e329-11ea-91a2-97ab16801eec", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/cockroachdb_Edited.mp3", + "Episodes Pubdate Date": "2016-04-14", + "Episodes Summary": "

Google has published papers on distributed systems such as BigTable, Chubby, and the Google File System. During this episode, we focus on a product that takes inspiration from Google’s Spanner project, a database that is built on a distributed monolithic sorted map.

CockroachDB is a scalable, survivable, consistent SQL database. Today’s guest Ben Darnell is the CTO of Cockroach Labs, and he joins us today to discuss SQL and NoSQL distributed databases. Ben explores the tradeoffs between these database types, and explains how CockroachDB provides many of the best features of both a SQL and a NoSQL distributed database.

", + "Episodes Title": "CockroachDB with Ben Darnell", + "Episodes Uid": "SED4875261678", + "Episodes Audio File": "88b86ab0fa6bef7cb75fdfab601fea5f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1vz", + "Episodes ID": "1e929778-e329-11ea-91a2-cbf4d873594f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CDN_Edited.mp3", + "Episodes Pubdate Date": "2016-04-15", + "Episodes Summary": "

CDN stands for content delivery network. A content delivery network is a system of distributed servers that delivers web pages and other web content. Without CDNs, the internet would be much slower, because CDNs function as a caching layer for most web resources.

Carl Gustas is an engineer at CacheFly, a popular content delivery network. He joins us today to discuss how CDNs work, and the different methods an engineer can use to take advantage of caching in a CDN.

", + "Episodes Title": "Managing a CDN with Carl Gustas", + "Episodes Uid": "SED5474108092", + "Episodes Audio File": "89750df76a00036d3c7b7485722d136b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1b5", + "Episodes ID": "24e100a6-e329-11ea-91a2-df1ac794dc53", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/18F_Edited_2.mp3", + "Episodes Pubdate Date": "2016-01-25", + "Episodes Summary": "

Governments are often laggards in the adoption of new technology. Every aspect of life, from transportation to healthcare, are being affected by the convergence of several trends including connected mobile devices, cloud storage and distributed systems. Yet federal services are in many cases still incapable of delivering the best and most affordable services to citizens.

The most visible instance of the U.S. government struggling to modernize was the implementation of Healthcare.gov. What was originally a modest budget for deploying the web marketplace of the Affordable Care Act ballooned into a costly implementation that required hiring external consultants and developers to fix. In response to this dysfunction, 18F was formed with the mission to simplify the government’s digital services. Sarah joins Software Engineering Daily to explain how and why 18F was formed, and how it plans to improve government from within in the years to come.

Sarah Allen is a Presidential Innovation Fellow who serves as a developer and product manager for 18F. She is also a co-founder of Bridge Foundry, an organization that helps encourage and empower people who are learning to code.

", + "Episodes Title": "Digital Transformation of Government with Sarah Allen", + "Episodes Uid": "SED9086360337", + "Episodes Audio File": "80cd87fda2c3cc878497af9b0e04b135.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1n0", + "Episodes ID": "22782790-e329-11ea-91a2-fff968b499e4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/answerdash_Edited_Final.mp3", + "Episodes Pubdate Date": "2016-02-25", + "Episodes Summary": "

University research produces numerous papers about software engineering. Unfortunately, many of the problems explored by these software engineering researchers have no actual application. These papers fall into The Black Hole of Software Engineering Research.

Andy Ko is an associate professor at the University of Washington. When he worked as a CTO of AnswerDash, he experimented with some of the software engineering research coming out of academia and industry. Today on Software Engineering Daily, we discuss Andy’s results. Our conversation spans the topics of education, big companies, and startups.

", + "Episodes Title": "Applying Software Research to Industry with Andy Ko", + "Episodes Uid": "SED2062728360", + "Episodes Audio File": "45c0133ce30a01a25bc39419b2141dc9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "78l", + "Episodes ID": "e945c4e6-e328-11ea-91a2-2f80cff24f7c", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_18_Anycart.mp3", + "Episodes Pubdate Date": "2020-05-18", + "Episodes Summary": "

There are many bad recipe web sites. Every time I navigate to a recipe website, it feels like my browser is filling up with spyware. The page loads slowly, everything seems broken, I can feel the 25 different JavaScript adtech tags interrupting each other. Whether I am searching for banana bread or a spaghetti sauce recipe, recipe sites usually make me lose my appetite.

Anycart is a recipe platform that allows users to buy all of the ingredients for the recipe and have those ingredients delivered. It’s a vertically integrated content site and delivery system. It is also beautifully designed and extremely performant. I learned about it from Zack Bloom, who works at Cloudflare, as he mentioned it as a case study in performance.

Rafael Sanches is a founder of Anycart, and he joins the show to talk about building a recipe delivery service, and the innovations in performance that were necessary to building it.

", + "Episodes Title": "Frontend Performance with Anycart’s Rafael Sanches", + "Episodes Uid": "SED5580960587", + "Episodes Audio File": "2a4db912cf1fa26074251b296148107f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "26k", + "Episodes ID": "14c71af2-e329-11ea-91a2-1ffbb93b4135", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/EFF_Nate_Edited.mp3", + "Episodes Pubdate Date": "2016-09-19", + "Episodes Summary": "

When the US government hacks its own citizens, The Electronic Frontier Foundation is often the best source of reporting to find out what laws the government has broken. When a change to the privacy policy of Google or Facebook is made, the Electronic Frontier Foundation is the best place to find out how that change in privacy exploits users. The Electronic Frontier Foundation provides legal defense and editorialism at the intersection of law and technology.
\nNate Cardozo joins the show today to discuss the mission of the EFF and his work at the organization. We have a wide ranging conversation, ranging from governments to corporations to Stuxnet to how the internal discussions at the EFF lead to the stances taken by the EFF.

", + "Episodes Title": "Electronic Frontier Foundation with Nate Cardozo", + "Episodes Uid": "SED2419593977", + "Episodes Audio File": "c7e2eee2f02884b927846ec936661e41.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6bv", + "Episodes ID": "ebb03c3e-e328-11ea-91a2-1fed0d71a321", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_07_LinkedinDataInfra.mp3", + "Episodes Pubdate Date": "2019-11-07", + "Episodes Summary": "

A large social network needs to develop systems for ingesting, storing, and processing large volumes of data.

Data engineering at scale requires multiple engineering teams that are responsible for different areas of the infrastructure.

Data needs to be structured coherently in order to minimize the data cleaning process. Machine learning models need to be developed, deployed, and iterated on at scale. Areas of the company which produce data need to be decoupled from the areas of the company which consume data, so that engineers throughout the company can reliably build tools on top of these large data sets.

In our previous episodes about LinkedIn, we covered two major components of LinkedIn’s data engineering systems: the Kafka infrastructure and the LinkedIn data platform used by engineers to productively build data applications.

Kapil Surlaker is a senior director of engineering at LinkedIn, and he joins the show to discuss the bigger picture of LinkedIn’s data infrastructure. Kapil works with teams across LinkedIn to understand the requirements for the products and internal tools, and translate those requirements into team structures and software platforms that let LinkedIn use data more productively.

We discuss a wide range of topics, including engineering management, the modern data platform, and LinkedIn’s adoption of public cloud.

Full disclosure: LinkedIn is a sponsor of Software Engineering Daily. 

", + "Episodes Title": "LinkedIn Data Engineering with Kapil Surlaker", + "Episodes Uid": "SED8948449404", + "Episodes Audio File": "5ad8f87b8bfce1ec48f7a1c67531a5bf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "11q", + "Episodes ID": "29eef3e6-e329-11ea-91a2-df32abea25ee", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Streaming_Edited_2.mp3", + "Episodes Pubdate Date": "2015-12-07", + "Episodes Summary": "

Real-time stream processing of data is becoming widely adopted in the efforts to manage and process “big data”. Some of the top frameworks for processing data streams include Storm, Spark, Samza and Flink.

Satish Mittal is an architect at InMobi, an ad platform that needs to deal with processing large volumes of ad data with tight time demands. He recently conducted an analysis of streaming frameworks to determine which of the tools was right for the application at InMobi.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Stream Processing with Satish Mittal", + "Episodes Uid": "SED5326898550", + "Episodes Audio File": "6f3ddb04d85790b38ec76c87d8a62511.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24b", + "Episodes ID": "1769cd86-e329-11ea-91a2-b39904985208", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Scaphold.io_Edited.mp3", + "Episodes Pubdate Date": "2016-08-08", + "Episodes Summary": "

GraphQL was open sourced out of Facebook, and gave developers a way to unify their different data sources into a single endpoint. Although the promise of GraphQL is appealing, the process of setting up a GraphQL server that can communicate with each disparate data source can prove to be complex.


\nScaphold.io provides GraphQL as a service, and today’s guests are the creators of Scaphold, Vince Ning and Michael Paris. Scaphold.io lets developers configure their schema, and hosts their data. Vince and Michael explain the basics of GraphQL, and also discuss how they are building a GraphQL as a service platform.Sponsors

", + "Episodes Title": "GraphQL as a Service with Scaphold.io", + "Episodes Uid": "SED9795677756", + "Episodes Audio File": "a0e875453a4fe21167adbeeb1de2d38d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ha", + "Episodes ID": "eb58c698-e328-11ea-91a2-c336d975e9cf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_03_Java13.mp3", + "Episodes Pubdate Date": "2019-12-03", + "Episodes Summary": "

Java has been popular since the 90s, when it started to be used as a programming language for enterprises. 

Today, Java is still widely deployed, but the infrastructure environment is dramatically different. Java is often deployed to containers in the cloud. If those containers can share resources, then those containers can share the same underlying Java infrastructure. 

Java 13 is the most recent public release of Java. The new features in Java 13 reflect the changing demands of modern application developers. Georges Saab is an engineer with Oracle who has been working on Java for more than a decade. He joins the show to discuss how Java development patterns are changing, and how the language is evolving to accommodate those changes, including discussion of garbage collection and dynamic application class data sharing.

", + "Episodes Title": "Java 13 with Georges Saab", + "Episodes Uid": "SED5090785555", + "Episodes Audio File": "3b887bd8d662c5e1b18630bea59a40b4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1z1", + "Episodes ID": "1cc78c50-e329-11ea-91a2-7ba18b116e1e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/decentralization_Edited.mp3", + "Episodes Pubdate Date": "2016-05-17", + "Episodes Summary": "

Almost a year ago, Software Engineering Daily aired a week of shows about decentralized technologies like Bitcoin, Ethereum, and IPFS. Bitcoin has established itself as a stable network, but it can only be used for financial transactions. Ethereum is a global computer built on a blockchain, but it does not have the adoption of Bitcoin. IPFS is a distributed data store with an incentivization layer where you can pay strangers to store your content.
\nToday’s guest is Karl Floersh, an engineer working on decentralized technology. Karl has written several posts about how to build decentralized applications, as well as how the future might look once these decentralized technologies have gotten traction.

", + "Episodes Title": "Decentralization: Ethereum, Bitcoin, and IPFS with Karl Floersh", + "Episodes Uid": "SED7787465150", + "Episodes Audio File": "8b8513ec33479755eaac684048df35b4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "16e8bba4-f7b2-11ea-a6bb-6b290e8cff78", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-16", + "Episodes Summary": "


", + "Episodes Title": "Superhuman with Rahul Vohra", + "Episodes Uid": "SED3657026513", + "Episodes Audio File": "54fc646deea75afceddfc3b87bad45ee.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 150, + "Episodes ID": "28497994-e329-11ea-91a2-eba614be80d0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Codefellows_Edited.mp3", + "Episodes Pubdate Date": "2015-12-17", + "Episodes Summary": "

Code Fellows in-person code school offering web and mobile development training in Seattle, Portland, and Chicago.

Dave Parker is the CEO of Code Fellows and organizer of Seattle Startup Week.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Code Fellows with Dave Parker", + "Episodes Uid": "SED7788601034", + "Episodes Audio File": "04b68b9e89299938b27337fc1e6dc9b4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6fz", + "Episodes ID": "eb8b8a42-e328-11ea-91a2-cfaed32791fb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_19_BubbleLowCode.mp3", + "Episodes Pubdate Date": "2019-11-19", + "Episodes Summary": "

The vision of code-free programming has existed for decades. Software engineers have always dreamed of empowering non-technical users with the same creative tools that programmers have access to. 

For many years, the underlying technology of the web was not powerful enough to make this dream a reality. Platforms such as WordPress, Squarespace, and Wix have allowed for some of the functionality of programming without writing code, but the scope of what those tools could accomplish was limited.

Today, the web has caught up. Improvements in browser technology and client devices mean that the end user has access to more powerful technology. The API economy encapsulates large amounts of functionality into cheap, well-defined functionality. No-code platforms are finding success among developers and non-developers, after persisting for several years as their technology matured.

Bubble is a code-free platform for building websites, startups, and internal tools. Emmanuel Straschnov and Joshua Haas are the founders of Bubble, and they join the show to tell the story of Bubble, and give their perspective on engineering, business, and the low-code movement. 

The story of Bubble is strikingly similar to that of no-code tools Airtable and Webflow, which we have covered in previous episodes. All of these products have taken years to get to maturity, with no shortcuts–only gritty, difficult engineering problems and performance improvements. Each of these no-code platforms has an inspiring story behind them, and persistent founders who eventually got their product to success.

", + "Episodes Title": "Bubble: Code-Free Programming with Emmanuel Straschnov and Joshua Haas", + "Episodes Uid": "SED3708021418", + "Episodes Audio File": "64dcd26eabe7a6c9134c4d14f0145f22.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7c6", + "Episodes ID": "e8dc9a8e-e328-11ea-91a2-a3a8ebfa954b", + "Episodes Original URL": "https://sd-profile-pictures.s3-us-west-2.amazonaws.com/adfree/2019_10_24_Redis_adfree.mp3", + "Episodes Pubdate Date": "2020-06-18", + "Episodes Summary": "

Originally published October 24, 2019. We are taking a few weeks off. We’ll be back soon with new episodes.

Redis is an in-memory database that persists to disk. Redis is commonly used as an object cache for web applications.

Applications are composed of caches and databases. A cache typically stores the data in memory, and a database typically stores the data on disk. Memory has significantly faster access times, but is more expensive and is volatile, meaning that if the computer that is holding that piece of data in memory goes offline, the data will be lost.

When a user makes a request to load their personal information, the server will try to load that data from a cache. If the cache does not contain the user’s information, the server will go to the database to find that information. 

Alvin Richards is chief product officer with Redis Labs, and he joins the show to discuss how Redis works. We explore different design patterns for making Redis high availability, or using it as a volatile cache, and we talk through the read and write path for Redis data. Full disclosure: Redis Labs is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Redis with Alvin Richards (Summer Break Repeat)", + "Episodes Uid": "SED7353326406", + "Episodes Audio File": "3d02e4ea77a38779cb58e77bf1728aa1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6cw", + "Episodes ID": "ebdfdf70-e328-11ea-91a2-4736cc054b7b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_24_Redis.mp3", + "Episodes Pubdate Date": "2019-10-24", + "Episodes Summary": "

Redis is an in-memory database that persists to disk. Redis is commonly used as an object cache for web applications.

Applications are composed of caches and databases. A cache typically stores the data in memory, and a database typically stores the data on disk. Memory has significantly faster access times, but is more expensive and is volatile, meaning that if the computer that is holding that piece of data in memory goes offline, the data will be lost.

When a user makes a request to load their personal information, the server will try to load that data from a cache. If the cache does not contain the user’s information, the server will go to the database to find that information. 

Alvin Richards is chief product officer with Redis Labs, and he joins the show to discuss how Redis works. We explore different design patterns for making Redis high availability, or using it as a volatile cache, and we talk through the read and write path for Redis data. Full disclosure: Redis Labs is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Redis with Alvin Richards", + "Episodes Uid": "SED5058647675", + "Episodes Audio File": "574b2c362a5096e45a7154b6d4ae7d06.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 730, + "Episodes ID": "e9b6b566-e328-11ea-91a2-3bc7c21a4e41", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_17_FacebookOpenStreetMap.mp3", + "Episodes Pubdate Date": "2020-04-17", + "Episodes Summary": "

Facebook applications use maps for showing users where to go. These maps can display businesses, roads, and event locations. Understanding the geographical world is also important for performing search queries that take into account a user’s location. For all of these different purposes, Facebook needs up-to-date, reliable mapping data.

OpenStreetMap is an open system for accessing mapping data. Anyone can use OpenStreetMap to add maps to their application. The data in OpenStreetMap is crowdsourced by users who submit updates to the OpenStreetMap database. Since anyone can submit data to OpenStreetMap, there is a potential for bad data to appear in the system.

Facebook uses OpenStreetMap for its mapping data, including for important applications where bad data would impact a map user in a meaningfully negative way. In order to avoid this, Facebook builds infrastructure tools to improve the quality of its maps. Saurav Mapatra and Jacob Wasserman work at Facebook on its mapping infrastructure, and join the show to talk about the tooling Facebook has built around OpenStreetMap data.

", + "Episodes Title": "Facebook OpenStreetMap Engineering with Saurav Mapatra and Jacob Wasserman", + "Episodes Uid": "SED8006278356", + "Episodes Audio File": "4b249910f646fefdc8f98787e7783f0d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7hi", + "Episodes ID": "e85662d4-e328-11ea-91a2-3366cdea0e6c", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_28_Indent.mp3", + "Episodes Pubdate Date": "2020-07-28", + "Episodes Summary": "

Across a company, there is a wide range of resources that employees need access to. Documents, S3 buckets, git repositories, and many others. As access to resources changes across the organization, a history of the changes to permissions can be useful for compliance and monitoring.

Indent is a system for simplifying access management across infrastructure. Indent allows users within an organization to request access to resources, and keeps logs of the changes to who can access those resources.

Fouad Matin and Dan Gillespie are the founders of Indent, and they join the show to talk through the application of access control management, and the architecture of Indent itself, which has numerous interesting engineering decisions within it.

Indent job opportunities

", + "Episodes Title": "Access Control Management with Fouad Matin and Dan Gillespie", + "Episodes Uid": "SED8330437751", + "Episodes Audio File": "2c160c5f164089ff9ebe10d675a68317.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6dn", + "Episodes ID": "ebc27336-e328-11ea-91a2-ebfc709d4ce1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_01_FBArturoBejar.mp3", + "Episodes Pubdate Date": "2019-11-01", + "Episodes Summary": "

Facebook leadership has a significant amount of engineers in its ranks, and engineers understand how to create an environment that appeals to other engineers. 

Engineers do not like working on projects that they are not interested in, so Facebook optimizes for matching engineers to enjoyable work. Engineers do not like taking orders from managers, so Facebook optimizes for a collaborative relationship between engineering and management.

Arturo Bejar was a director of engineering at Facebook for more than five years. Arturo managed a team that built site integrity tools, as well as the Product Infrastructure team, which created the groundbreaking React and GraphQL open source tools. Arturo has a deep understanding of what engineers want from a manager, and this is apparent in the results of the teams he has worked with.

Arturo also cares deeply about the human side of technology. When he was at Facebook, he started the Compassion Project, which looked at ways that technology could help support people through difficult times, and alleviate suicide and bullying.

Arturo joins the show for a conversation about engineering management, humanity, and the ethos of Facebook.

Articles by Arturo Bejar

Managing Your Manager

Challenges and Opportunities in Communication Online: Summary and Full Version

", + "Episodes Title": "Facebook Leadership with Arturo Bejar", + "Episodes Uid": "SED2557294084", + "Episodes Audio File": "ceafe36a6a53dabedc77a2316982cfc6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2cq", + "Episodes ID": "0e82cd12-e329-11ea-91a2-835ec6f5b142", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/mesos-and-kubernetes_edited_1.mp3", + "Episodes Pubdate Date": "2016-12-14", + "Episodes Summary": "

Mesos and Kubernetes are tools for distributed systems management. Kubernetes is built with an emphasis on running services, whereas Mesos is commonly used for a wider variety of workloads, including data infrastructure like Spark and Kafka. Mesos can also be used as a platform to provide resource management for Kubernetes.

Dharmesh Kakadia is the author of Apache Mesos Essentials, and has spent time studying both Mesos and Kubernetes. He joins the show to explain the strengths of both platforms, and how they can be used together. In addition to dissecting Mesos and Kubernetes, we had a wide-ranging discussion, from cloud providers to software architecture to business strategy.

***

If you are in the Bay Area on January 11th, come to the Software Engineering Daily meetup. There will be awesome speakers, food, and a positive atmosphere. Find more information on softwareengineeringdaily.com or at the Software Engineering Daily meetup page.

", + "Episodes Title": "Mesos, Kubernetes, and Infrastructure of the Future with Dharmesh Kakadia", + "Episodes Uid": "SED9056167771", + "Episodes Audio File": "c3a0b9365edfa1a1fda50965dd11ce79.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7cv", + "Episodes ID": "e8c8964c-e328-11ea-91a2-cb04c79baedb", + "Episodes Original URL": "https://sd-profile-pictures.s3-us-west-2.amazonaws.com/adfree/2019_07_25_EnvoyMobilewithMattKlein_adfree.mp3", + "Episodes Pubdate Date": "2020-06-24", + "Episodes Summary": "

Originally published July 25, 2019. We are taking a few weeks off. We’ll be back soon with new episodes.

Envoy is an open source edge and service proxy that was originally developed at Lyft. 

Envoy is often deployed as a sidecar application that runs alongside a service and helps that service by providing features such as routing, rate limiting, telemetry, and security policy. Envoy has gained significant traction in the open source community, and has formed the backbone of popular service mesh projects such as Istio.

Envoy has been mostly used as a backend technology, but the potential applications of Envoy include frontend client applications as well. The goal of Envoy is to make the network easier to work with–and the network includes client applications such as mobile apps running on a phone.

Envoy Mobile is a network proxy for mobile applications. Envoy Mobile brings many of the benefits of Envoy to the mobile client ecosystem. It provides mobile developers with a library that can simplify or abstract away many of the modern advances that have been made in networking in recent years, such as HTTP2, gRPC, and QUIC.

Matt Klein is the creator of Envoy, and he joins the show to discuss Envoy Mobile. Matt describes how the networking challenges of mobile applications are similar to those of backend systems and cloud infrastructure. We discuss the advances in networking technology that Envoy Mobile helps bring to the mobile ecosystem, and also touch on the scalability challenges that Matt is seeing at Lyft.

", + "Episodes Title": "Envoy Mobile with Matt Klein (Summer Break Repeat)", + "Episodes Uid": "SED9671774431", + "Episodes Audio File": "4f19d5a548ac67bc412927cbd8692b83.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7fj", + "Episodes ID": "e88b668c-e328-11ea-91a2-1bb643345f3a", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_13_Metaflow.mp3", + "Episodes Pubdate Date": "2020-07-13", + "Episodes Summary": "

Netflix runs all of its infrastructure on Amazon Web Services. This includes business logic, data infrastructure, and machine learning. By tightly coupling itself to AWS, Netflix has been able to move faster and have strong defaults about engineering decisions. And today, AWS has such an expanse of services that it can be used as a platform to build custom tools.

Metaflow is an open source machine learning platform built on top of AWS that allows engineers at Netflix to build directed acyclic graphs for training models. These DAGs get deployed to AWS as Step Functions, a serverless orchestration platform.

Savin Goyal is a machine learning engineer with Netflix, and he joins the show to talk about the machine learning challenges within Netflix, and his experience working on Metaflow. We also talk about DAG systems such as AWS Step Functions and Airflow.

", + "Episodes Title": "Metaflow: Netflix Machine Learning Platform with Savin Goyal", + "Episodes Uid": "SED7793251247", + "Episodes Audio File": "690e52c5977c72ed662e3f3b46f72370.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7aj", + "Episodes ID": "e8f49602-e328-11ea-91a2-bf4424b69d81", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_11_Grafana.mp3", + "Episodes Pubdate Date": "2020-06-11", + "Episodes Summary": "

Grafana is an open source visualization and monitoring tool that is used for creating dashboards and charting time series data. Grafana is used by thousands of companies to monitor their infrastructure. It is a popular component in monitoring stacks, and is often used together with Prometheus, ElasticSearch, MySQL, and other data sources.

The engineering complexities around building Grafana involve the large number of integrations, the highly configurable ReactJS frontend, and the ability to query and display large data sets. Grafana also must be deployable to cloud and on-prem environments.

Torkel Ödegaard is a co-founder of Grafana Labs, and joins the show to talk about his work on the open source project and the company he is building around it.

", + "Episodes Title": "Grafana with Torkel Ödegaard", + "Episodes Uid": "SED3272178964", + "Episodes Audio File": "141824d82ad1f14d0a591c6f54285ce8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1d1", + "Episodes ID": "244701a4-e329-11ea-91a2-cf6120e3bf74", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Matplotlib_Edited.mp3", + "Episodes Pubdate Date": "2016-02-01", + "Episodes Summary": "

Matplotlib is a python plotting library inspired by MATLAB. It allows developers to easily visualize their data using simple functions. In this episode, Jeff and Ben discuss why visualizing data is integral for the human experience, and how they it can make drawing conclusions from data more meaningful. Ben relates this to his experience studying atmospheric data in the wild, and how his work as a researcher drives his need to visualize the vast amounts of raw data generated by weather systems.

Ben Root is a core contributor to Matplotlib and works as a scientific programmer for Atmospheric and Environmental Research Inc.

", + "Episodes Title": "Matplotlib with Ben Root", + "Episodes Uid": "SED8312430266", + "Episodes Audio File": "ba7839d2c7da6745d597eeb742209e62.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "18z", + "Episodes ID": "26445bd2-e329-11ea-91a2-cb2516958cdb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Druid_Edited_2.mp3", + "Episodes Pubdate Date": "2016-01-07", + "Episodes Summary": "

Druid is a column-oriented distributed database that excels as a data warehousing solution for fast queries on large data sets.

Fangjin Yang is a core contributor to Druid, and is currently co-founder and CEO of Imply, which helps build interactive analytics powered by Druid.

", + "Episodes Title": "Architecting Distributed Databases with Fangjin Yang", + "Episodes Uid": "SED2852825125", + "Episodes Audio File": "c9e84a3f600a3c76323f693eec47071a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1sg", + "Episodes ID": "1ff7edb6-e329-11ea-91a2-8b360a0152c5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Segment_Edited.mp3", + "Episodes Pubdate Date": "2016-03-25", + "Episodes Summary": "

Today’s guest is Calvin French-Owen, the CTO of Segment, a tool that companies use to aggregate their analytics into once place. As Segment has scaled, the company has had to restructure its etire technical architecture. Microservices, containers, Amazon Web Services, and dev ops are a few of the topics that Calvin and I explore in our conversation, so this is a great episode for anyone who is trying to understand the relationships between those different subjects.

Segment’s product unifies analytics from different services and puts them into one centralized place. Full disclosure: Segment is a sponsor of Software Engineering Daily. For most of this episode, we don’t even talk about the product, we talk about the back end engineering behind the product.

", + "Episodes Title": "Developer Analytics with Calvin French-Owen", + "Episodes Uid": "SED4528413771", + "Episodes Audio File": "f763a74802d930ad9ca32925d524704f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "21e", + "Episodes ID": "1a52b63e-e329-11ea-91a2-47ee92c4e1d4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Guacamole_Edited.mp3", + "Episodes Pubdate Date": "2016-06-28", + "Episodes Summary": "

In order to use a remote desktop experience, software engineers have a limited number of options, and most of them are proprietary, like VMWare or Oracle. Remote desktop is a functionality that many engineers use every day, so it is surprising that the open source world has taken awhile to displace the functionality of proprietary software.
\nIn 2010, Mike Jumper started working on Guacamole, a way to access remote desktops through your browser. Over the last six years, Mike has worked continuously to create a simple, open-source software tool to access desktops remotely, and this year Guacamole joined the Apache Incubator and became Apache Guacamole. In this episode, we discuss the past, present, and future of remote desktop, and the technical internals of Apache Guacamole.

", + "Episodes Title": "Apache Guacamole and Remote Desktop with Mike Jumper", + "Episodes Uid": "SED4935201332", + "Episodes Audio File": "28088d383a4dc90445fb9e089f174846.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ik", + "Episodes ID": "eebe92e0-e328-11ea-91a2-ff9d14345f48", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_29_KubernetesWorkloadsBrianGrant.mp3", + "Episodes Pubdate Date": "2019-03-29", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Google has been building large-scale scheduling systems for more than fifteen years.

Google Borg was started around 2003, giving engineers at Google a unified platform to issue long-lived service workloads as well as short-lived batch workloads onto a pool of servers. Since the early days of Borg, the scheduler systems built by Google have matured through several iterations. Omega was an effort to improve the internal Borg system, and Kubernetes is an open source container orchestrator built with the learnings of Borg and Omega.

A scheduling system needs to be able to accept a wide variety of workload types and find compute resources within a cluster to schedule those workloads onto.

There is a wide variety of potential workloads that could be scheduled–batch jobs, stateful services, stateless services, and daemon services. Different workloads can have different priority levels. A high priority workload should be able to find compute resources quickly, and a low priority workload can wait longer to find resources.

Brian Grant is a principal engineer at Google. He joins the show to talk about his experience building workload schedulers and designing APIs for engineers to interface with those schedulers.    

", + "Episodes Title": "Workload Scheduling with Brian Grant", + "Episodes Uid": "SED9155140495", + "Episodes Audio File": "5241c347ca4ae6bb60621f45fcfb720c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5fi", + "Episodes ID": "ef12a57e-e328-11ea-91a2-d76adabe3f93", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_08_Netlify.mp3", + "Episodes Pubdate Date": "2019-03-08", + "Episodes Summary": "

Cloud computing started to become popular in 2006 with the release of Amazon EC2, a system for deploying applications to virtual machines sitting on remote data center infrastructure . With cloud computing, application developers no longer needed to purchase expensive server hardware. Creating an application for the Internet became easier, cheaper, and simpler.

As the cloud has become popular, new ways of deploying applications have emerged. A developer with a web app has so many different options.

You can host your app on an Amazon EC2 server, which will require you to manage cloud infrastructure in case your server crashes. You can deploy your app to Heroku, which gives your cloud deployment better uptime guarantees for a higher price than Amazon EC2. Or you can use Linode, or Microsoft Azure, or Google Cloud.

There is such a large market for cloud computing that the world of cloud providers serves more niches every year. In past episodes we have explored a variety of different cloud providers, and the markets they target.

Pivotal Cloud Foundry is for managing complex distributed systems applications, typically with large teams. Firebase is a cloud provider that simplifies the developer experience for applications with small teams. Spotinst is a cloud provider that emphasizes low cost. Zeit is a cloud provider that is built to manage applications through serverless “functions-as-a-service” like AWS Lambda.

In today’s episode, Mathias Biilman Christensen, CEO of Netlify, joins the show. Netlify is a cloud provider that was built for modern web projects. Netlify represents the convergence of several trends in software development converging: static site deployment, serverless functions, a desire to have a “no-ops” deployment with minimal management, and the rise of newer tools like GraphQL and Gatsby.

Mathias explores these trends in detail, and explores the technical challenges of building Netlify. He was a great guest, capable of talking about difficult backend problems that require writing C++, as well as the frontend world of JavaScript frameworks.

One announcement before we begin: we are having a $5000 hackathon. The $5000 hackathon is for a new product we’ve been working on: FindCollabs. FindCollabs is a platform for finding collaborators and building projects. Whether you are an engineer, a musician, a designer, a videographer, or an artist, FindCollabs lets you find people and collaborate. To try out FindCollabs, just go to FindCollabs.com, you can make a project or you can join someone else’s project. And it’s very easy to make these projects–you don’t need to have anything built yet–you need to have a vision for what you want to build. And to find out about the hackathon, go to findcollabs.com/hackathon. We are giving away $5000 in cash to the coolest projects that get built before Sunday April 14th. So I recommend getting started early, finding some people to collaborate with, and building some cool stuff!

", + "Episodes Title": "Netlify with Mathias Biilmann Christensen", + "Episodes Uid": "SED3639051537", + "Episodes Audio File": "c780d6fd5b617ce7fca42e2e37114887.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ky", + "Episodes ID": "f3e91e84-e328-11ea-91a2-dfde6e191d1b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_16_PumpandDumpswithBruno.mp3", + "Episodes Pubdate Date": "2018-03-16", + "Episodes Summary": "

Cryptocurrency speculation has pulled in a large population of people who do not know what they are investing in. If you hear about an investment of $1000 turning into $1M, it’s tempting to get sucked in yourself.

For most of these everyday people, the game is completely rigged. A large percentage of market activity is driven by “pump and dumps.” A pump and dump is a conspiracy to trick investors into buying a currency.

An insider group commits the pump and dump. This is accomplished by purchasing the currency ahead of time, then promoting it via Twitter, Telegram, and reddit. The outsiders fall victim to the promotion of the currency, and buy it after the fast run-up in value. The currency then crashes, and the outsiders are left “holding the bag.”

Pump and dumps are not a new phenomenon—they have happened with worthless penny stocks. One thing that is new is the ease with which new cryptocurrencies are being created. Launching an ICO is easy. Marketing it is cheap. Pumping and dumping has never been more accessible. And buying them is quite easy as well. This has led to a perfect storm of naive investment capital.

Bruno Skvorc is the CEO and owner of Bitfalls, a site with blog posts, news, and information about cryptocurrencies. He wrote a post called “The Anatomy of a Pump and Dump Group,” which details how cryptocurrency pump and dumps have been used to swindle investors out of millions of dollars.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

If you are looking for an internship, apply to the Software Engineering Daily internship, at softwaredaily.com/jobs. And if you are looking to recruit engineers, you can post jobs for your company there as well–it’s completely free to post jobs and to apply. We are hoping to find interns to contribute to the Software Daily open source project–and if you want to see what we are building, go to SoftwareDaily.com or check out our apps in the  iOS or Android app store. They have all 650 of our episodes, with recommendations, related links, discussions and more.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Crypto Pump and Dumps with Bruno Skvorc", + "Episodes Uid": "SED6455097592", + "Episodes Audio File": "c3aa48ba3d1fc00ec895cfd0234920bb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2es", + "Episodes ID": "0b0bf53c-e329-11ea-91a2-2ffc154e97fd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/columnardata_edited_fixed.mp3", + "Episodes Pubdate Date": "2017-01-13", + "Episodes Summary": "

Column-oriented data storage allows us to access all of the entries in a database column quickly and efficiently. Columnar storage formats are mostly relevant today for performing large analytics jobs.

For example, if you are a bank, and you want to get the sum of all of the financial transactions that took place on your system in the last week, you don’t want to iterate through every row in a database of transactions. It is more efficient to just look at the column for the amount of money, and ignore things like timestamp and user id.

Julien Le Dem co-created Parquet, a file format for storing columnar data on disk. Jacques Nadeau is a VP of Apache Arrow, a format for in-memory columnar representation. They are both part of Dremio, and they join the show to talk about how columnar data is stored, processed, and shared between systems like Spark, Hadoop, and Python.

", + "Episodes Title": "Columnar Data: Apache Arrow and Parquet with Julien Le Dem and Jacques Nadeau", + "Episodes Uid": "SED8857797808", + "Episodes Audio File": "7e6461b63a3ca48a3715219ffef5d0b1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23k", + "Episodes ID": "192535f2-e329-11ea-91a2-f3c6c94ccd5b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/arrow_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-07-18", + "Episodes Summary": "

In a typical data analytics system, there are a variety of technologies interacting. HDFS for storing files, Spark for distributed machine learning, pandas for data analysis in Python–each of these different technologies has a different format for how data is represented.

Serialization and deserialization between these different formats causes significant latency across the overall system. Apache Arrow is a tool for improving performance of in-memory analytics systems, and today’s guest Uwe Korn explains how Arrow enables these systems with interoperability.

", + "Episodes Title": "Apache Arrow with Uwe Korn", + "Episodes Uid": "SED8402015004", + "Episodes Audio File": "9fc2b4b6df49776f9928e01a09f91333.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 247, + "Episodes ID": "17bb38f6-e329-11ea-91a2-1b38e06a3883", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Mobycraft_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-08-02", + "Episodes Summary": "

MobyCraft is a client-side Minecraft mod to manage and visualize Docker containers. MobyCraft was created by Aditya Gupta. I met him at DockerCon, where he gave a presentation about his project. He also discussed his interaction with the Netflix team, who integrated MobyCraft with their container management tool called Titus.

You can watch a video online of Titus managing hundreds of 3-D containers within MineCraft. In this episode, we discuss how and why Aditya built MobyCraft, and how he got started programming at such a young age.

", + "Episodes Title": "Mobycraft with Aditya Gupta", + "Episodes Uid": "SED2356992787", + "Episodes Audio File": "e68b5c7c8d76e8478020e85f2c99a7a0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2f7", + "Episodes ID": "0a82cdf2-e329-11ea-91a2-9bd0241d6727", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/inferno_edited.mp3", + "Episodes Pubdate Date": "2017-01-19", + "Episodes Summary": "

Over the past few years, React has become the most popular front end JavaScript framework. As React has matured, the open source community around React has identified areas for improvement. Since React itself is too mature to refactor completely, new projects have been started to take the best aspects of React and start from scratch.

Inferno is an extremely fast, React-like JavaScript library for building modern user interfaces. Dominic Gannaway is the creator of Inferno and in this episode he joins Caleb Meredith for an interview about Inferno and other React-like JavaScript libraries.

", + "Episodes Title": "Inferno with Dominic Gannaway", + "Episodes Uid": "SED2649464817", + "Episodes Audio File": "a969e890cbb7ca9efd263578ab6dc55e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3cd", + "Episodes ID": "f50a3b9a-e328-11ea-91a2-df1d7b1bd25a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/kernighan_ad_free.mp3", + "Episodes Pubdate Date": "2017-12-28", + "Episodes Summary": "

Originally published January 6, 2016

Brian Kernighan is a professor of computer science at Princeton University and the author of several books, including The Go Programming Language and The C Programming Language, a book more commonly referred to as K&R. Professor Kernighan also worked at Bell Labs alongside Unix creators Ken Thompson and Dennis Ritchie and contributed to the development of Unix.

", + "Episodes Title": "Language Design with Brian Kernighan Holiday Repeat", + "Episodes Uid": "SED7978543548", + "Episodes Audio File": "564abaf058c8d83f5bc07a77ff6fda79.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "20o", + "Episodes ID": "1b17b31c-e329-11ea-91a2-b715f6aefc74", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/gender_cs_google.mp3", + "Episodes Pubdate Date": "2016-06-14", + "Episodes Summary": "

Google researcher Jennifer Wang co-wrote a paper called “Gender Differences in Factors Influencing Pursuit of Computer Science and Related Fields”. The paper focuses on a survey of 1700 high school and college students, and takes a statistical approach to understanding why women are not pursuing computer science.

In our conversation, Jennifer talks about the two influences that lead to fewer women in computer science: encouragement and exposure. The problem of encouragement: women often do not receive encouragement to go into computer science. The problem of exposure: women are often unaware that computer science even exists. On this episode, we explore the roots of these problems, and other results of her demographic study of young students.

", + "Episodes Title": "Female Pursuit of Computer Science with Jennifer Wang", + "Episodes Uid": "SED8345323984", + "Episodes Audio File": "d3efb16537cd89bed5660ce3301575d8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ah", + "Episodes ID": "10363252-e329-11ea-91a2-d739aa008df7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/debuggingstories_edited.mp3", + "Episodes Pubdate Date": "2016-11-19", + "Episodes Summary": "

Everyone has debugging stories. We have all had the experience of wrestling with a seemingly impossible bug for days until we finally come to a solution. In today’s episode, Haseeb Qureshi retells some of his favorite debugging stories: The case of the 500-mile email, Debugging Behind the Iron Curtain, and My Hardest Bug Ever.

", + "Episodes Title": "Debugging Stories with Haseeb Qureshi", + "Episodes Uid": "SED5827123094", + "Episodes Audio File": "f4d6a320b67cfe2bf7045ccc4d9bd3c7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "z5", + "Episodes ID": "2bef0bae-e329-11ea-91a2-b3f8bf1fa24d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Godin_Edited.mp3", + "Episodes Pubdate Date": "2015-11-18", + "Episodes Summary": "

Seth Godin is a writer, speaker, and entrepreneur. He is the author of many books, including most recently, What To Do When It’s Your Turn.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Software and Entrepreneurship with Seth Godin", + "Episodes Uid": "SED6619577765", + "Episodes Audio File": "00f095fecf705db7390532c23856bb8b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yt", + "Episodes ID": "f6aca29e-e328-11ea-91a2-0f030974fe47", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/IndustrialIoT.mp3", + "Episodes Pubdate Date": "2017-08-30", + "Episodes Summary": "

Sensors are being attached to trains, lightposts, and all kinds of factory equipment. Industrial machinery gives off high volumes of data that can be captured, stored, and processed with machine learning in order to improve workflows and ensure safety.

Jayson Delancey works at GE, which is building tools and systems to manage large IoT deployments. The full stack for enterprise IoT involves tools for managing thousands of sensors; databases for storing all the data that is coming off of these devices; authentication and authorization systems for enforcing security. There is a lot to do.

In this episode, Jayson surveys some of the technology GE is building with Predix, its industrial IoT platform. He also talked about some of the large scale IoT deployments he has seen.

", + "Episodes Title": "Industrial IoT with Jayson Delancey", + "Episodes Uid": "SED7499869650", + "Episodes Audio File": "41f9c927c5492bc0079010c021a5cb01.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ck", + "Episodes ID": "ef57f8e0-e328-11ea-91a2-cf1ecc846499", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_18_Datree.mp3", + "Episodes Pubdate Date": "2019-02-18", + "Episodes Summary": "

The nature of software projects is changing. Projects are using a wider variety of cloud providers and SaaS tools. Projects are being broken up into more git repositories, and the code in those repositories are being deployed into small microservices.

With the increased number of tools, repositories, and deployment targets, it can become difficult to manage software policy. “Policy” defines how different parts of an application can behave. Which parts of your application can access an Amazon S3 bucket? Which parts of your application can communicate with the authentication microservice? Which developers are allowed to push a new build to production?

Shimon Tolts is the CTO and co-founder of Datree, a platform for policy enforcement and code compliance. He joins the show to talk about continuous delivery, configuration management, and policy enforcement. He also explains the motivation for his company Datree, which performs analysis across a user’s GitHub repo to map the committers, code components, and repositories.

", + "Episodes Title": "Policy Enforcement with Shimon Tolts", + "Episodes Uid": "SED9501483513", + "Episodes Audio File": "8ad2463a1113a1f8b2392948cfc1e047.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 103, + "Episodes ID": "2b2103da-e329-11ea-91a2-47098d62bdf9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/FLIF_post_gband.mp3", + "Episodes Pubdate Date": "2015-11-24", + "Episodes Summary": "

Free Lossless Image Format (FLIF) is a novel lossless image format which outperforms PNG, lossless WebP, lossless BPG and lossless JPEG2000 in terms of compression ratio.

Jon Sneyers is one of the core contributors to FLIF.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Free Lossless Image Format with Jon Sneyers", + "Episodes Uid": "SED4937879757", + "Episodes Audio File": "41bbda8c8a581d57873421e53b1355bd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 200000000, + "Episodes ID": "0b79e39e-e329-11ea-91a2-a30386c2a6fa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/email_infrastructure_edited.mp3", + "Episodes Pubdate Date": "2017-01-10", + "Episodes Summary": "

A company like Pinterest has millions of transactional emails to send to people. The scalability challenges of sending high volumes of email mean that it makes more sense for most companies to use an email as a service product rather than building their own.

Chris McFadden is the VP of engineering and cloud operations at SparkPost and he joins the show to explain the architecture of SparkPost’s email as a service product. SparkPost started as an on-premise email technology for large enterprises, and evolved into a SaaS product. In 2014, the company migrated to the cloud, which has changed its infrastructure as well as its operational model.

Full disclosure: SparkPost is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Email Infrastructure with Chris McFadden", + "Episodes Uid": "SED5366524391", + "Episodes Audio File": "565d8e721544cba802bae803c00bd725.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2u8", + "Episodes ID": "f7785ff6-e328-11ea-91a2-3fda487b8018", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ReactNativeInterfaces.mp3", + "Episodes Pubdate Date": "2017-07-07", + "Episodes Summary": "

Airbnb is a company that is driven by design. New user interfaces are dreamed up by designers and implemented for web, iOS, and Android. This implementation process takes a lot of resources, but it used to take even more before the company started using React Native. React Native allows Airbnb to reuse components effectively.

React Native works by presenting a consistent model for the user interface regardless of the underlying platform, and emitting a log of changes to that user interface. The underlying platform translates those changes into platform specific code.

Leland Richardson is an engineer at Airbnb. In today’s episode, he explains how Airbnb uses React Native, how React Native works, and the future of the platform.

Check out our new topic feeds, in iTunes or wherever you find your podcasts. We’ve sorted all 500 of our old episodes into categories like business, blockchain, cloud engineering, JavaScript, machine learning, and greatest hits. Whatever specific area of software you are curious about, we have a feed for you. Check the show notes for more details.

React Europe Talk 

Airbnb article on react-sketchapp

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "React Native Interfaces with Leland Richardson", + "Episodes Uid": "SED3106512318", + "Episodes Audio File": "3dc98ab4e8122a9703e871ccd6ddb44d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2mq", + "Episodes ID": "fe2eb4ee-e328-11ea-91a2-cb0666ff0ec8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Ransomware.mp3", + "Episodes Pubdate Date": "2017-04-27", + "Episodes Summary": "

Ransomware uses software to extort people. A piece of ransomware might arrive in your inbox looking like a PDF, or a link to a website with a redirect. Ransomware is often distributed using social engineering. The email address might resemble someone you know, or a transactional email from a company like Uber or Amazon.

Tim Gallo and Allan Liska are authors of the O’Reilly book Ransomware: Defending Against Digital Distortion. They join me to describe the 5 stages of ransomware: deployment, installation, command and control, destruction, and extortion. Tim and Allan describe conditions under which it might make sense to pay the extortion, and some frightening recent cases of ransomware impacting the real world.

We would love to get your feedback on Software Engineering Daily. Please fill out the listener survey, available on softwareengineeringdaily.com/survey. Also–Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to download the Ransomware transcript.

", + "Episodes Title": "Ransomware with Tim Gallo and Allan Liska", + "Episodes Uid": "SED7103607201", + "Episodes Audio File": "98dc3dc28f4102f52da5b1ac0c773f55.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "22v", + "Episodes ID": "19e2ff24-e329-11ea-91a2-439671dce44d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Scalable_Architecture.mp3", + "Episodes Pubdate Date": "2016-07-09", + "Episodes Summary": "

Lee Atchison spent seven years at Amazon working in retail, software distribution, and Amazon Web Services. He then moved to New Relic, where he has spent four years scaling the company’s internal architecture. From his decade of experience at fast growing web technology companies, Lee has written the book Architecting for Scale, from O’Reilly.

As an application scales, it becomes significantly more complicated while at the same time receiving more traffic. The intersection of these two problems leads to a variety of discussions around availability, risk management, and microservices. Lee and I didn’t have time to get through everything in his book Architecting for Scale, but if you enjoy this episode, check out the book. Lee also spoke recently at the O’Reilly Velocity conference in Santa Clara, so you can check out his talk.
\nWe are giving away a free ticket to O’Reilly’s Velocity 2016 conference in New York. If you want to be entered to win that ticket, send a tweet about your favorite SE Daily episode about dev ops or web performance, and tag software_daily, as well as #velocityconf.

", + "Episodes Title": "Scalable Architecture with Lee Atchison", + "Episodes Uid": "SED9365146357", + "Episodes Audio File": "530e81dd922f7c70f957c751cde347e4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3kw", + "Episodes ID": "f3f2abb6-e328-11ea-91a2-f3c7aef7109d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_14_Web3.mp3", + "Episodes Pubdate Date": "2018-03-14", + "Episodes Summary": "

Most applications today run on a cloud provider like AWS. They are built with a framework like Ruby on Rails. They use a set of APIs like Stripe and Twilio for middleware services. This is the era of “web 2.0.”

With decentralized systems, we are starting to get a feel for what “web 3.0” might feel like. The futuristic idea of “web 3.0” works off of the following idea: instead of using a centralized service owned by a single company, you might purchase your computation and storage from a network of nodes. The nodes will be running peer-to-peer software that competes on price.

Fabian Vogelsteller works on Web3.js, a JavaScript library for interfacing with the Ethereum blockchain. He also works on Mist, a browser for Ethereum. Fabian joins the show to discuss the difference between decentralized apps and centralized apps—and to explain why we need to build a bridge between those two worlds.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Web3 with Fabian Vogelsteller", + "Episodes Uid": "SED3321504150", + "Episodes Audio File": "5651cfb6209ee936644d5abd8a6c372b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "21d", + "Episodes ID": "1a6c5aa8-e329-11ea-91a2-5bcd8e2dbe45", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/cloudgov_fixed.mp3", + "Episodes Pubdate Date": "2016-06-26", + "Episodes Summary": "

18F is an organization that is building the 21st century digital government. In order to build online government services that have the high quality of modern cloud applications, 18F built Cloud.gov, a platform-as-a-service that can be used to stand up web applications for divisions of the government.
\nAidan Feldman helped build Cloud.gov, and on today’s episode he dissects its architecture. Cloud.gov is built on CloudFoundry, which sits on top of a special version Amazon Web Services built specifically for the US government. We also explore how application development works at 18F, and how 18F has built a culture that reflects an ideal mix of public service and fast-moving innovation.

", + "Episodes Title": "Cloud.gov with Aidan Feldman", + "Episodes Uid": "SED4943176805", + "Episodes Audio File": "e19482b6aa1bf997ce89079fa437bd58.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2p1", + "Episodes ID": "fd574b08-e328-11ea-91a2-1bdd9ce92d5d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/topic_feeds_episode.mp3", + "Episodes Pubdate Date": "2017-05-03", + "Episodes Summary": "

Listeners have had difficulty finding the Software Engineering Daily content they want to listen to.

We are creating new podcast feeds to address this.

The content on each podcast feed is mutually exclusive from the other feeds, except for the main feed and “Greatest Hits.”

You can now find the following podcast feeds in iTunes and Google Play:

Every new episode goes into 2 feeds:

An episode can potentially be in 3 feeds if it is also in Greatest Hits.

If you subscribe to all of the feeds including Software Engineering Daily (main feed), you will receive 2 notifications for every new episode.

With the different feeds, we hope you can curate your own ideal SE Daily listening experience. Thanks for listening to Software Engineering Daily and please let us know what you think of the new feeds.

A few recommendations:

We hope the rollout of these new feeds goes smoothly. If you have issues, please email me, notify us in Slack, or tweet at us.

", + "Episodes Title": "New Topic Feeds", + "Episodes Uid": "SED5915715152", + "Episodes Audio File": "e949e890e99f6b3528f5c7c7f40d9fd0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2cn", + "Episodes ID": "0e989020-e329-11ea-91a2-03e969784a95", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/adfraudeverywhere_edited_2.mp3", + "Episodes Pubdate Date": "2016-12-13", + "Episodes Summary": "

Advertising fraud is easy, legal, and extremely profitable. A fraudster can set up a website, scrape content from the internet, and run programmatic advertisements against that website. The fraudster can then purchase bot traffic. Those bots will visit the page, consume advertisements, and return profit to the owner of the page.

In a past life, Shailin Dhar worked for a company that set up these types of advertising fraud schemes. He was fascinated by the industry in the same way that plenty of people get fascinated with the fast-moving market dynamics that are enabled by modern software. But over time, the novelty wore off and Shailin realized how big the fraud problem is and how much it was hurting people.

In today’s episode Shailin and I discuss how bots and poorly aligned incentives lead to systemic failures and significant financial loss for brands who purchase advertising.

", + "Episodes Title": "Ad Fraud Everywhere with Shailin Dhar", + "Episodes Uid": "SED6790960184", + "Episodes Audio File": "825a905fc927f97efac3efd4c8c5440c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ly", + "Episodes ID": "006c44f6-e329-11ea-91a2-7f357be340f7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/fb_oss_edited_fixed.mp3", + "Episodes Pubdate Date": "2017-04-14", + "Episodes Summary": "

Facebook’s open source projects include React, GraphQL, and Cassandra. These projects are key pieces of infrastructure used by thousands of developers–including engineers at Facebook itself.

These projects are able to gain traction because Facebook takes time to decouple the projects from their internal infrastructure and clean up the code before releasing them into the wild. Facebook has high standards for what they are willing to release.

Tom Occhino manages the React team at Facebook and works closely with engineers to determine what projects make sense to open source. In this episode, Preethi Kasireddy interviews Tom about how Facebook thinks about open source–what went right with React, why it makes sense for Facebook to continue to release new open source projects, and how full-time employees at Facebook interact with that open source codebase.

We would love to get your feedback on Software Engineering Daily. Please fill out the listener survey, available on softwareengineeringdaily.com/survey. Also–Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

Pete Hunt: React: Rethinking best practices — JSConf EU 2013

", + "Episodes Title": "Facebook Open Source with Tom Occhino", + "Episodes Uid": "SED8861229584", + "Episodes Audio File": "3fc2b569b689f2bc56ed27f4df8ae294.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2b8", + "Episodes ID": "0fa7137e-e329-11ea-91a2-cbbf8de5f39b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/mongoservice_editedfixed1.mp3", + "Episodes Pubdate Date": "2016-12-01", + "Episodes Summary": "

Eight years ago, MongoDB was an internal project at 10gen, a company that was trying to build a platform-as-a-service out of open-source components. The team at 10gen realized that the platform-as-a-service play would be too complex, and difficult to build. Since MongoDB was the most valuable component of that project, they narrowed their focus to this new document-oriented database.

In today’s episode, MongoDB CTO Eliot Horowitz describes the history of MongoDB the open source project, as well as the company–which recently released a managed cloud service. Eliot explained how the company has architected the MongoDB Atlas service on top of AWS, and why developers often want a managed service as their database rather than managing database servers themselves.

Full disclosure–MongoDB is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Database as a Service with Eliot Horowitz", + "Episodes Uid": "SED4485556008", + "Episodes Audio File": "930e698f8c793ed21100a29e1be21e50.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1zz", + "Episodes ID": "1bc98a2e-e329-11ea-91a2-4376511203da", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Practical_Dev.mp3", + "Episodes Pubdate Date": "2016-06-03", + "Episodes Summary": "

Most programmers spend lots of their time reading content about software. Since our field changes so rapidly, engineers consume news and editorials voraciously, trying to keep up with the impossibly fast pace. The Practical Dev is a collection of blog posts, editorials, and interviews that was created to help with that end.

Ben Halpern is the creator of Practical Dev, and he joins the show to discuss software editorialism. The goal of the Practical Dev to help developers grow and learn, and Ben is working towards that goal by providing a platform for engineers to write long-form content.

", + "Episodes Title": "Software Editorialism with Practical Dev’s Ben Halpern", + "Episodes Uid": "SED7564998053", + "Episodes Audio File": "cc725130eec4ac51dd3e43f71aa0261e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ym", + "Episodes ID": "f6cbae6e-e328-11ea-91a2-e38215b7562f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/MapboxARKit.mp3", + "Episodes Pubdate Date": "2017-08-21", + "Episodes Summary": "

Augmented reality is coming at us fast. Every large tech company is rumored to be building an AR product. Microsoft HoloLens is already available to developers. Pokemon Go, the most popular augmented reality product today, was made by a company that was spun out of Google. But Apple seems to be ahead of everyone.

Apple’s ARKit is a set of tools for developers to build augmented reality applications. The applications people are building with ARKit are remarkable, and two of those early adopters join the show today for an interview.

Jesse Bounds and Siyu Song work at Mapbox, a company that makes mapping, navigation, and location search SDKs. Location is natural companion to augmented reality. If I am walking down the street with a pair of augmented reality glasses on, those glasses can augment the world with information based on my location.

Because the fit between AR and mapping is so natural, Mapbox has been rapidly experimenting to build up an expertise in AR. As a result, Jesse and Siyu make for great guests to talk about what engineers can build with ARKit today and what might be possible in the future.

", + "Episodes Title": "Augmented Reality with Jesse Bounds and Siyu Song", + "Episodes Uid": "SED2129414695", + "Episodes Audio File": "a7d39c1693a4d4c71744581ad2c55cfb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 207, + "Episodes ID": "1b8077a8-e329-11ea-91a2-6bde5d270cd9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Management.mp3", + "Episodes Pubdate Date": "2016-06-09", + "Episodes Summary": "

Engineering managers start out as engineers. Eventually, there is a fork in their career road where an engineer can choose to move up into management or continue on as an engineer in a more senior role. Changing to management involves an increase in responsibilities, a different set of goals to focus on.

Jon Emerson was working at Google as an engineer when a project he was working on started to get more attention. He moved into management, and spent several years at Google as a manager. Today, he works at Hired as a director of engineering, leading four different teams. Full disclosure: Hired is a sponsor of Software Engineering Daily, but this episode is not about Hired itself. We do start out with a discussion of the hiring process, because of Jon’s domain expertise around hiring, but most of our conversation focuses on the role of a manager, and the role of a director.

Most of the episodes of Software Engineering Daily focus on the day-to-day life of an engineer, so it was interesting to get a perspective from someone higher up the management chain, who has more visibility over entire software projects.

", + "Episodes Title": "Management and Hiring with Jon Emerson", + "Episodes Uid": "SED4663183401", + "Episodes Audio File": "c0d2756573263f54fda4c272cca7617e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1y7", + "Episodes ID": "1ce81498-e329-11ea-91a2-531247419667", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Crate.mp3", + "Episodes Pubdate Date": "2016-05-13", + "Episodes Summary": "

Distributed databases are difficult to operate, and Crate.io wants to change that. Crate is a fast, scalable, easy-to-use SQL database that is built to run in containerized environments.

An average software company runs several databases–MySQL for relational store, MongoDB for a document database, HDFS for blob storage and data warehouse, elastic search for search. On today’s show, Jodok Batlogg from Crate discuss the distributed architecture of Crate, and breaks down the use cases, from Microservices to data warehousing.

", + "Episodes Title": "Crate.io and Distributed SQL with Jodok Batlogg", + "Episodes Uid": "SED2901384382", + "Episodes Audio File": "70a2082e7aba4d3dfaccc439451e3019.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2gm", + "Episodes ID": "07f37366-e329-11ea-91a2-134fada39230", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Go_Data_Science.mp3", + "Episodes Pubdate Date": "2017-02-09", + "Episodes Summary": "

Data science is typically done by engineers writing code in Python, R, or another scripting language. Lots of engineers know these languages, and their ecosystems have great library support. But these languages have some issues around deployment, reproducibility, and other areas. The programming language Golang presents an appealing alternative for data scientists.

Daniel Whitenack transitioned from doing most of his data science work in Python to writing code in Golang. In this episode, Daniel explains the workflow of a data scientist and discusses why Go is useful. We also talk about the blurry line between data science and data engineering, and how Pachyderm is useful for versioning and reproducibility. Daniel works at Pachyderm, and listeners who are more curious about it can check out the episode I did with Pachyderm founder Joe Doliner.

", + "Episodes Title": "Go Data Science with Daniel Whitenack", + "Episodes Uid": "SED4557094080", + "Episodes Audio File": "58ce938084fea96ada9191709f811de3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1y2", + "Episodes ID": "1dbdb544-e329-11ea-91a2-bb3e6f26c5d0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Brian_Rue.mp3", + "Episodes Pubdate Date": "2016-04-29", + "Episodes Summary": "

Exception monitoring services and log management services are two sides of a gradient. Exception monitoring services capture and aggregate the problems that occur on your application. Log management services aggregate all of your logs, so that you can decide for yourself what constitutes a problem.

Brian Rue from Rollbar joins the show today to talk about Rollbar’s exception monitoring architecture, and the competitive landscape of these technology products. Every software engineer wants track the problems with an application, but some developers need more information than others–and that ends up changing how these error aggregation services are architected. This is an interesting conversation on the business of SaaS products for developers, and the architecture of a distributed system designed to monitor and aggregate errors.

", + "Episodes Title": "Distributed Systems and Exception Monitoring with Brian Rue", + "Episodes Uid": "SED2639226327", + "Episodes Audio File": "d93ef6b6a368c5e0d447bc8f2cfc23f7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1z3", + "Episodes ID": "1ca04bb8-e329-11ea-91a2-eb096ae54671", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Netflix.mp3", + "Episodes Pubdate Date": "2016-05-19", + "Episodes Summary": "

At Netflix, 500 billion events and 1.3 petabytes of data are ingested by the system per day.  This includes video viewing activities, error logs, and performance events. On today’s episode, we dive deep into the data pipeline of Netflix, and how it evolved from their 1.0 version to the modern 2.0 version.

Before listening to this episode, check out the blog post that inspired it.

", + "Episodes Title": "Netflix’s Data Pipeline with Steven Wu", + "Episodes Uid": "SED4609009813", + "Episodes Audio File": "ec5c92f0f2aaae4c63e4fed76d3b77c4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1yb", + "Episodes ID": "1d2f5704-e329-11ea-91a2-535f7a966996", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Button.mp3", + "Episodes Pubdate Date": "2016-05-09", + "Episodes Summary": "

Applications on your phone can talk to each other, but the way that apps interact is still far from the way that web pages interact.

Mike Wakerly is the CTO of Button, a service that connects mobile apps to each other. By embedding a component from Button into your app, you can easily request the functionality of an app while you are in a different app. In this episode, Mike and I discuss the future of mobile, and the problems of app stores today.

We also explore how mobile application context switching has improved, and how that creates business opportunities that are much more interesting than advertising.

", + "Episodes Title": "Mobile Apps and Monetization with Mike Wakerly", + "Episodes Uid": "SED3074241791", + "Episodes Audio File": "14828a42275db93bd140429be67e7f37.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 267, + "Episodes ID": "1540214a-e329-11ea-91a2-03f63bc378ca", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Slack_Architecture.mp3", + "Episodes Pubdate Date": "2016-09-12", + "Episodes Summary": "

Slack is a chat application that is rapidly growing in popularity. The focus of Slack is to create a polished, responsive tool for productivity that cuts down on the emailing, context switching, and useless meetings that take place at a typical enterprise.

Keith Adams, the chief architect at Slack, joins the show to explain how those high level principles translate into engineering decisions.

Keith previously worked for 7 years at Facebook, contributing heavily to the tools that make PHP easier to develop with at scale. Slack’s core product is also built with PHP, and Keith discusses the similarities and differences between scaling Facebook and Slack.

", + "Episodes Title": "Slack’s Architecture with Keith Adams", + "Episodes Uid": "SED3434194184", + "Episodes Audio File": "5641cee91758467b3d31004049faad42.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "dj", + "Episodes ID": "35beaf7c-e329-11ea-91a2-b7ad89917eed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/joyent_bcantrill_fixed.mp3", + "Episodes Pubdate Date": "2015-08-26", + "Episodes Summary": "

Containers are a central component of the DevOps movement. Joyent provides simple, secure deployment of containers with bare metal speed on container-native infrastructure

Bryan Cantrill is the CTO of Joyent, the father of DTrace and an OS kernel developer for 20 years.

", + "Episodes Title": "Containers with Bryan Cantrill from Joyent", + "Episodes Uid": "SED9440263069", + "Episodes Audio File": "52224859d56ab941f2dfc9bcf35ed452.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ju", + "Episodes ID": "331c687c-e329-11ea-91a2-87fb43706405", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/mjackson_react.mp3", + "Episodes Pubdate Date": "2015-09-16", + "Episodes Summary": "

It offers users a way to build full-fledged web apps from their React components.

Michael Jackson works on React Router and is the founder of ReactJS Training. He will be speaking at the upcoming QCon San Francisco.

", + "Episodes Title": "React Router, Flux, and Web Debates with Michael Jackson", + "Episodes Uid": "SED4522051605", + "Episodes Audio File": "153c34791954e3095caf10d723d4af2d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "fe", + "Episodes ID": "3501f148-e329-11ea-91a2-b7506d4072a4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ripple_david_schwartz.mp3", + "Episodes Pubdate Date": "2015-09-01", + "Episodes Summary": "

David Schwartz is Chief Cryptographer for Ripple Labs.

", + "Episodes Title": "Cryptofinancial Security with David Schwartz of Ripple Labs", + "Episodes Uid": "SED9110530136", + "Episodes Audio File": "54cbb3aedea882844baaa3a1df48fd0f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "nu", + "Episodes ID": "31aa9414-e329-11ea-91a2-93598e7f4e95", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/sarah_aerni.mp3", + "Episodes Pubdate Date": "2015-09-25", + "Episodes Summary": "

Pivotal makes software platforms and database products to enable enterprises to make use of their data.

Sarah Aerni is principal data scientist at Pivotal.

", + "Episodes Title": "Data Science at Pivotal with Sarah Aerni", + "Episodes Uid": "SED4308104670", + "Episodes Audio File": "56a622de7c3ac3a8b6ae182441b84781.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "bm", + "Episodes ID": "36733f8c-e329-11ea-91a2-6b07ebd6d3dc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/neo4j_ryan.mp3", + "Episodes Pubdate Date": "2015-08-22", + "Episodes Summary": "

Ryan Boyd is a developer advocate for Neo4j, an open-source graph database.

", + "Episodes Title": "Graph Databases with Ryan Boyd of Neo4j", + "Episodes Uid": "SED1898443120", + "Episodes Audio File": "a8e8bfc121b287bc5035de3fab597c24.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "g1", + "Episodes ID": "34a1fe3c-e329-11ea-91a2-832e3d437997", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/bruce_schneier.mp3", + "Episodes Pubdate Date": "2015-09-03", + "Episodes Summary": "

Bruce Schneier is a security researcher and author of Data and Goliath.

", + "Episodes Title": "Security and Privacy with Bruce Schneier", + "Episodes Uid": "SED5604228475", + "Episodes Audio File": "bfbc0267d8d2b664a58e57d2d50280e7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "p6", + "Episodes ID": "30e5ea88-e329-11ea-91a2-d3333f2b15e1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/yad_ML.mp3", + "Episodes Pubdate Date": "2015-10-01", + "Episodes Summary": "

Yad Faeq returns to the podcast to discuss data science at a high level, and rescue Software Engineering Daily from the threat of the hype vortex.

Yad is a software engineer, currently working on machine learning applications. Yad first appeared on Software Engineering Daily on Episode 0, the inaugural show.

", + "Episodes Title": "Data Science Overview with Yad Faeq", + "Episodes Uid": "SED3877492240", + "Episodes Audio File": "79980743e406f714a3a5c0ed1c08a231.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 96, + "Episodes ID": "3712a220-e329-11ea-91a2-6f5538044bd6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/melanie_blockchains.mp3", + "Episodes Pubdate Date": "2015-08-11", + "Episodes Summary": "

Melanie Swan is a science and technology innovator and philosopher at the MS Futures Group. She founded the Institute for Blockchain Studies, and is the author of Blockchain: Blueprint for a New Economy.

", + "Episodes Title": "Blockchains with Melanie Swan", + "Episodes Uid": "SED5039054653", + "Episodes Audio File": "adcdab1fcfd1f657900597e164f638a7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "41k", + "Episodes ID": "f292b2c0-e328-11ea-91a2-270d5eea7fb5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_21_DatabaseReliabilityEngineering.mp3", + "Episodes Pubdate Date": "2018-06-20", + "Episodes Summary": "

Over the last decade, cloud computing made it easier to programmatically define what infrastructure we have running, and perform operations across that infrastructure. This is called “infrastructure as code.” Whether you want to backup a database, deploy a new version of a service, or introduce a new tier of load balancers, the changes that we make across our infrastructure can be done programmatically, instead of through a series of manual steps.

As infrastructure got turned into code, operations people started working more like developers, and developers began to do the work of operations–a convergence known as “devops.” At Google, this “devops” movement was manifested in a role called “site reliability engineer.” In previous shows, we have explored site reliability engineering culture.

Laine Campbell is a senior VP of engineering at Fastly, and the author of the book Database Reliability Engineering. In this book, Laine describes how the ideas of site reliability engineering can be extended to databases. Laine joins the show to discuss the book, and how engineering teams can build effective workflows around databases.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Database Reliability Engineering with Laine Campbell", + "Episodes Uid": "SED6945983614", + "Episodes Audio File": "fe4a2df785f2862da66e43cd82f8a1e6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yj", + "Episodes ID": "f6dd15dc-e328-11ea-91a2-eb2d5ae1458d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/QATesting.mp3", + "Episodes Pubdate Date": "2017-08-15", + "Episodes Summary": "

Quality assurance testing is a form of testing that closely mirrors user behavior. Sometimes it is manual, sometimes it is automated. Automated QA tests are scripts that validate correct data representation as the application mechanically runs through high-level workflows–like a login page. Manual QA testers act out use cases of an application to see if there are any bugs that were missed during automated test cases. Manual QA testing is often necessary for complex applications where it is not possible to enumerate all potential workflows within a script.

Different companies have radically different workflows for QA testing. There are a variety of ticketing systems, testing frameworks, and team chat applications that play a role in a tester’s daily life. QASymphony is a platform for testing tools that integrates with other popular technologies to centralize a QA testing workflow.

Jonathan Alexander is the CTO at QASymphony. He’s also the author of Codermetrics: Analytics for Improving Software Teams. He joins the show to discuss the past and present of QA and his strategies for managing the team that is building QASymphony. Thanks to Kevin Wolf for the intro.

", + "Episodes Title": "QA Testing with Jonathan Alexander", + "Episodes Uid": "SED9999137079", + "Episodes Audio File": "8ab0a165b8c2502c2afc438ff2d024ff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3sl", + "Episodes ID": "f2fa4d04-e328-11ea-91a2-1b1de0b0af82", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_21_VoiceRecognitionAnalysis.mp3", + "Episodes Pubdate Date": "2018-05-21", + "Episodes Summary": "

A sample of the human voice is a rich piece of unstructured data. Voice recordings can be turned into visualizations called spectrograms. Machine learning models can be trained to identify features of these spectrograms. Using this kind of analytic strategy, breakthroughs in voice analysis are happening at an amazing pace.

Rita Singh researches voice at Carnegie Mellon University. Her work studies the high volume of latent data that is available in the human voice. As she explains, just a small fragment of a human voice can be used to identify who a speaker is. Your voice is as distinctive as your fingerprint.

Your voice can also reveal medical conditions. Features of the human voice can be strongly correlated with psychiatric symptom severity, and potentially heart disease, cancer, and other illnesses. The human voice can even suggest a person’s physique–your height, weight, and facial features.

In this episode, Rita explains the machine learning techniques that she uses to uncover the hidden richness of the human voice.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Voice with Rita Singh", + "Episodes Uid": "SED7141085714", + "Episodes Audio File": "82e90311492a75b54d81f7217402a7bd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ml", + "Episodes ID": "ee6d8b0c-e328-11ea-91a2-4fc3bb867fd4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_22_ServerlessRuntime.mp3", + "Episodes Pubdate Date": "2019-04-22", + "Episodes Summary": "

RECENT UPDATES:

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat.

Google’s options for running serverless workloads started with App Engine. App Engine is a way to deploy an application in a fully managed environment. Since the early days of App Engine, managed infrastructure has matured and become more granular.

We now have serverless databases, queueing systems, machine learning tools, and functions as a service. Developers can create fully managed, event-driven, highly scalable systems with less code and less operations.

Different cloud providers are taking different approaches to offering serverless runtimes. Google’s approach involves the open source Knative project and a hosted platform for running Knative workloads called Cloud Run.

Steren Giannini is a product manager at Google working on serverless tools. He joins the show to discuss Google’s serverless projects and the implementation details in building them.

", + "Episodes Title": "Serverless Runtimes with Steren Giannini", + "Episodes Uid": "SED8976056052", + "Episodes Audio File": "069c3383ecf42ec30f5616f6feb272f5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5d6", + "Episodes ID": "ef4614a4-e328-11ea-91a2-ebb74ae316e6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_22_ReactNativeRearchitecture.mp3", + "Episodes Pubdate Date": "2019-02-22", + "Episodes Summary": "

React Native allows developers to build native applications for iOS and Android using components written in the React JavaScript framework. These ReactJS components render to native application code by going over a JavaScript bridge, a message bus that communicates between JavaScript code and native iOS or Android runtimes.

For most mobile application use cases, React Native works well. But in some cases, the platform suffers from performance issues due to the functionality of the JavaScript bridge. For example, mobile games with high demands on graphics, networking, and fast real-time updates to the UI can stutter when using React Native.

To address the performance issues of React Native, the core team working on React Native at Facebook is rearchitecting the React Native runtime within a project called Fabric. Fabric consists of changes to the threading model, the data handling system, and the JavaScript bridge.

Chris Severns and Lee Johnson work at G2i, a group of React and React Native specialists. Chris and Lee join the show to discuss the rearchitecture, including the engineering history of React, the technical debt within the React project, and the vision that the React team has for the future. We also discuss Google’s Flutter project, a cross-platform native framework with a different architectural model than React Native.

", + "Episodes Title": "React Native Rearchitecture with G2i Team", + "Episodes Uid": "SED5854154006", + "Episodes Audio File": "be978c704a61fcf183ca0e67aa4d9fc3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yl", + "Episodes ID": "f6d462de-e328-11ea-91a2-cbe96b53f305", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/GatsbyJS.mp3", + "Episodes Pubdate Date": "2017-08-17", + "Episodes Summary": "

GatsbyJS is a framework for building web applications for JavaScript. Gatsby’s original goal was to allow users to create super fast static web sites that could be hosted and served efficiently at a low cost. Most web pages have components from a framework like React or Angular that need to render after the user requests them. This rendering can sometimes require additional requests to external data sources, causing the page to take longer to load.

Gatsby uses GraphQL to pull in data at build time and pre-render as much of a site as possible using React’s server side rendering. When a page built with Gatsby is served to a user, as much of the page has been rendered as possible, so that the browser can quickly load everything on the page without additional network requests.

Kyle Mathews is the creator of GatsbyJS. He joins the show to describe why he created Gatsby–the high level goals and low level engineering decisions. We also discuss how Kyle intends to take Gatsby beyond just an open source project and turn it into a business.

", + "Episodes Title": "GatsbyJS with Kyle Mathews", + "Episodes Uid": "SED6668663276", + "Episodes Audio File": "c5fd70fd0aebed71c396e549d2d0029e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2u5", + "Episodes ID": "f7e1092a-e328-11ea-91a2-ab7be30f538a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ChrisDixon.mp3", + "Episodes Pubdate Date": "2017-06-30", + "Episodes Summary": "

The history of computing can be thought of as a series of ideas rather than objects. From Aristotle’s formalization of the syllogism, to Alan Turing’s model for an all-purpose computing machine, to Satoshi Nakamoto’s distributed transaction ledger–these breakthroughs did not come in the form of polished, tangible objects. In fact, the objects which end up changing computing fundamentally are often built from ideas that seemed trivial at first glance.

Chris Dixon is a general partner at venture capital firm Andreessen Horowitz and is the author of the article How Aristotle Created the Computer. One job of a venture capitalist is to be early in identifying the ideas that will evolve into influential, tangible objects. In this article, Chris examined several instances in the history of computing where ideas that looked weird and impractical at first glance ended up being world-changing. Recent examples we discussed are blockchains and neural networks.

Chris recently wrote a great article about crypto tokens.

Check out our new topic feeds, in iTunes or wherever you find your podcasts. We’ve sorted all 500 of our old episodes into categories like business, blockchain, cloud engineering, JavaScript, machine learning, and greatest hits. Whatever specific area of software you are curious about, we have a feed for you. Check the show notes for more details.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Computer Logic with Chris Dixon", + "Episodes Uid": "SED9277847050", + "Episodes Audio File": "3b53e2ecde4cb74c63b5ccec686fd82b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2x2", + "Episodes ID": "f722c1fe-e328-11ea-91a2-0736cefe89f1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RoundtableJJGK.mp3", + "Episodes Pubdate Date": "2017-07-26", + "Episodes Summary": "

Building a startup requires constant evaluation of tradeoffs. At the earliest stage, the founders evaluate different ideas. Once an idea is settled on, the company develops strategies for finding early customers and growing. As the company develops traction, the operators consider ways to scale further or partner with an acquirer.

Joseph Jacks and Greg Koberger are two founders who have been on the show previously. JJ started Kismatic, the earliest company completely focused on Kubernetes. Kismatic was acquired by Apprenda last year. Greg runs Readme.io, a company that provides beautiful documentation as a service.

In this episode, Greg and Joe share their thoughts on running and scaling startups–engineering concerns, scaling strategies, and discussions of what to build and what to buy.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Startup Roundtable with Joseph Jacks and Gregory Koberger", + "Episodes Uid": "SED1528164520", + "Episodes Audio File": "815d355576d131eeaf1708138610f454.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ov", + "Episodes ID": "f35bada6-e328-11ea-91a2-c378b158150b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_25_SifteryEngineering.mp3", + "Episodes Pubdate Date": "2018-04-25", + "Episodes Summary": "

There are hundreds of different databases. There are tens of continuous delivery products. There is an ocean of cloud providers and CRM systems and monitoring platforms and sales prospecting tools.

The range of available software products is so diverse that it can be overwhelming to figure out which products to buy. Siftery is a company that was started to index software products and help buyers make decisions. Siftery can build a data set from your web site or from your Google account, assess your software stack, and compare those software products to others on the market.

In a previous show with Ayan Barua, we discussed how engineers should explore the question of build vs. buy. In today’s episode, Ayan joins the show to discuss how Siftery has evolved, and the engineering behind Siftery products. A newer Siftery product called Track can ingest banking transactions, QuickBooks records, or other transaction histories and use that information to compile the cost structure of your software company, and we spent the latter part of our conversation discussing why and how they built it.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Siftery Engineering with Ayan Barua", + "Episodes Uid": "SED3882014210", + "Episodes Audio File": "899eb6ae5880ca79d43278d0c5b2389a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5l6", + "Episodes ID": "ee942316-e328-11ea-91a2-c330bc17883a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_11_ConsulServiceMesh.mp3", + "Episodes Pubdate Date": "2019-04-11", + "Episodes Summary": "

RECENT UPDATES:

FindCollabs $5000 Hackathon Ends Saturday April 15th, 2019

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

Consul is a tool from HashiCorp that allows users to store and retrieve information from a highly available key/value data store. Consul is used for storage of critical cluster information, such as service IP locations and configuration data. A service interacts with Consul via a daemon process on the node of that service. The daemon process periodically shares information with the Consul server over a gossip UDP protocol and can share data on a more immediate basis using TCP.

Consul’s functionality has increased recently to add secure service connectivity. Consul Connect allows services to establish mutual TLS encryption with each other. The addition of mutual TLS to the Consul feature set is closely incidental with Consul gaining a title of “service mesh.”

Service mesh is an increasingly popular pattern that can encompass a variety of features: load balancing, security policy management, service discovery, and routing. Tools which offer self-described “service mesh” functionality include Linkerd, Kong, AWS App Mesh, Solo.io Gloo, and Google’s Istio open source project.

Paul Banks is the engineering lead of Consul at HashiCorp. He joins the show to talk about the service mesh category and the past, present, and future of Consul.

", + "Episodes Title": "Consul Service Mesh with Paul Banks", + "Episodes Uid": "SED5701173219", + "Episodes Audio File": "54de8fbd1fd4bd885ac6dd087958bc77.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3gf", + "Episodes ID": "f478b8c8-e328-11ea-91a2-f3b1c7914b83", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_05_LinkedinResilience.mp3", + "Episodes Pubdate Date": "2018-02-05", + "Episodes Summary": "

How do you build resilient, failure tested systems? Redundancy, backups, and testing are all important. But there is also an increasing trend towards chaos engineering–the technique of inducing controlled failures in order to prove that a system is fault tolerant in the way that you expect.

In last week’s episode with Kolton Andrus, we discussed one way to build chaos engineering as a routine part of testing a distributed system. Kolton discussed his company Gremlin, which injects failures by spinning up a Gremlin container and having that container induce network failures, memory errors, and filled up disks. In this episode, we explore another insertion point for testing controlled failures, this time from the point of view of Linkedin.

Linkedin is a social network for working professionals. As Linkedin has grown, the increased number of services has led to more interdependency between those services. The more dependencies a given service has, the more partial failure cases there are. That’s not to say there is anything wrong with having a lot of service dependencies–this is just the way we build modern applications. But it does suggest that we should try to test the failures that can emerge from so many dependencies.

Bhaskaran Devaraj and Xiao Li are engineers at Linkedin, and are working on a project called Waterbear, with the goal of making the infrastructure more resilient.

Linkedin’s backend system consists of a large distributed application with thousands of microservices communicating between each other. Most of those services communicate over Rest.li, a proxy for standardizing interactions between services. Rest.li can assist with routing, AB testing, circuit breaking, and other aspects of service-to-service communication. This proxy can also be used for executing controlled failures. As services are communicating with each other, creating a controlled failure can be as simple as telling your proxy not to send traffic to downstream services.

If that sounds confusing, don’t worry, we will explain it in more detail.

In this episode, Bhaskaran and Xiao describe their approach to resilience engineering at Linkedin–including the engineering projects and the cultural changes that are required to build a resilient software architecture.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Linkedin Resilience with Bhaskaran Devaraj and Xiao Li", + "Episodes Uid": "SED7957295683", + "Episodes Audio File": "9e5d02161b03e2288ec7f0aebb9a2bf4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2qc", + "Episodes ID": "fb3334d6-e328-11ea-91a2-1b21e1d2af17", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/OilandGasData.mp3", + "Episodes Pubdate Date": "2017-05-18", + "Episodes Summary": "

Public data is not always so accessible. It is nice when you can request data simply by making an API call, but that is the exception rather than the rule–especially when we are talking about data managed by the government. Oil and gas drilling data falls into this category.

Oseberg is a company that is building a tool for analyzing oil and gas data. Oseberg is a rich dashboard for knowledge workers to query and visualize the data. Evan Anderson is the CEO of Oseberg, and he joins me to discuss building a business where the data is hard to acquire.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Oil and Gas Data with Evan Anderson", + "Episodes Uid": "SED5640853804", + "Episodes Audio File": "d9fea3529b6a44e66280548c5e21c5ed.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48y", + "Episodes ID": "f1ceefc0-e328-11ea-91a2-e3325da00f04", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_08_SelfDrivingGeorgeHotz.mp3", + "Episodes Pubdate Date": "2018-08-08", + "Episodes Summary": "

In the smartphone market there are two dominant operating systems: one closed source (iPhone) and one open source (Android). The market for self-driving cars could play out the same way, with a company like Tesla becoming the closed source iPhone of cars, and a company like Comma.ai developing the open source Android of self-driving cars.

George Hotz is the CEO of Comma.ai. Comma makes hardware devices that allow users with “normal” cars to be augmented with advanced cruise control and lane assist features. This means you can take your own car–for example, a Toyota Prius–and outfit your car to have something similar to the Tesla Autopilot. Comma’s hardware devices cost under $1000 to order online.

George joins the show to explain how the Comma hardware and software stack works in detail–from the low level interface with a car’s CAN bus to the high level machine learning infrastructure.

Users who purchase the Comma.ai hardware drive around with a camera facing the front of their windshield. This video is used to orient the state of the car in space. The video from that camera also gets saved and uploaded to Comma’s servers. Comma can use this video together with labeled events from the user’s driving experience to crowdsource their model for self-driving.

For example, if a user is driving down a long stretch of highway, and they turn on the Comma.ai driving assistance, the car will start driving itself and the video capture will begin. If the car begins to swerve into another lane, the user will take over for the car and the Comma system will disengage. This “disengagement” event gets labeled as such, and when that data makes it back to Comma’s servers, Comma can use the data to update their models.

George is very good at explaining complex engineering topics, and is also quite entertaining and open to discussing the technology as well as other competitors in the autonomous car space. I have not been able to get many other people on the show to talk about autonomous cars, so this was quite refreshing! I hope to do more in the future.

", + "Episodes Title": "Self-Driving Engineering with George Hotz", + "Episodes Uid": "SED2554820469", + "Episodes Audio File": "185c2a48980bbc7bdcfa9a7ef642b346.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2g3", + "Episodes ID": "08dd3f6e-e329-11ea-91a2-7367beb2ee70", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/endofcloud_edited.mp3", + "Episodes Pubdate Date": "2017-02-03", + "Episodes Summary": "

Cloud computing has pushed computation away from our own private servers and into virtual machines running on a data center. In the world of cloud computing, processing is centralized in these data centers, and our smartphone and laptop application performance suffers from having high latency between the client and the cloud server.

As machine learning proliferates, the current model of cloud computing will become too slow. A small difference in the time it takes to refresh a machine learning model for a drone or car could be the difference between life and death.

Computation will move to the edge. The same drones, cars, and IoT devices that need their models updated quickly will form a peer-to-peer network with which to distribute time-sensitive tasks. One bellwether for this real time peer-to-peer network might be Uber’s Ringpop, a fault-tolerant application layer sharding system.

In such an edge computing model, your device could federate a complex request out to other nearby devices that have spare processing capacity, pay for those compute cycles using Bitcoin, and receive a response without any request to a centralized cloud server. The cloud servers would still be around, but they would be responsible for doing offline computation across large data sets.

This prediction was described by Peter Levine, a partner at Andreessen Horowitz in his talk “The End of Cloud Computing”. In this episode, Peter discusses the pressures that our pushing toward edge computing and away from the cloud.

", + "Episodes Title": "The End of Cloud Computing with Peter Levine", + "Episodes Uid": "SED4609389335", + "Episodes Audio File": "606704d2a5d7271e92ae9b3df4736027.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3li", + "Episodes ID": "f3e40732-e328-11ea-91a2-e79dec8b217f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_19_ShapeshiftOperations.mp3", + "Episodes Pubdate Date": "2018-03-19", + "Episodes Summary": "

A financial exchange is an operationally intensive business. You have customers making a high volume of transactions, your service has to be low latency and highly available, and you are dealing with a lot of money. A cryptocurrency exchange has all of the complexity of a typical financial exchange–and then some additional complexity.

Shapeshift is a cryptocurrency exchange that allows users to buy and sell digital assets–Bitcoin, Ethereum, Litecoin, and lots of other currencies. Shapeshift also has a set of tools and APIs that allow developers to build higher level applications that transact in cryptocurrencies. Shapeshift’s CEO is an early cryptocurrency entrepreneur named Erik Voorhees, who will appear on the show in the near future.

Today’s guest Jon is the COO of Shapeshift–he handles the operations of the company. He prefers not to use his last name, because Shapeshift is particularly sensitive to social engineering attacks. We’ll get into why that is in the episode–and explore lots of other topics too. How to scale a cryptocurrency exchange, the products Shapeshift offers, and some of the near-death experiences that Shapeshift has had. After all–it is a startup, and every startup has moments where it seems like the company will die.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

If you are looking for all 700 episodes of Software Engineering Daily, check out our apps on the iOS or Android app store. We’ve got tons of episodes on blockchains, business, distributed systems, and tons of other topics. If you want to become a paid subscriber to Software Engineering Daily, you can hear all of our episodes without ads–you can subscribe at softwaredaily.com. And all of the code for our apps is open source. If you are looking for an open source community to be a part of, come check out github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Shapeshift Operations with Jon Shapeshift", + "Episodes Uid": "SED9774795315", + "Episodes Audio File": "03dea2fe8498e3adb5f2d434ea302f71.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "33d", + "Episodes ID": "f629984a-e328-11ea-91a2-f7819fea775f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/TrustMetrics.mp3", + "Episodes Pubdate Date": "2017-10-06", + "Episodes Summary": "

Despite all the problems with online advertising, ads are not going away. Advertising is fundamental to the modern Internet economy.

In previous episodes of Software Engineering Daily, we have mostly dissected the problems of adtech–bots, tracking, fraud, brand safety. We have talked about some solutions–for example, JavaScript tags that you can put on a page to identify a bot before you serve it an ad. But these solutions don’t get the job done completely, because it isn’t possible to reliably identify bots. Today we explore another solution for adtech: the whitelist.

Marc Goldberg is the CEO of Trust Metrics, a company that provides whitelisting for advertisers. A whitelist is a list of domains that are acceptable to run your advertisements on. In order to build a whitelist, you need to review thousands of sites to judge which ones are reasonable places to publish an advertisement. Marc joins the show to describe how to build and scale a system for reviewing websites and judging whether they are safe to run ads against.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! The Software Engineering Daily open source community is building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend. If you are interested in contributing, check out github.com/softwareengineeringdaily–or send me an email: jeff@softwareengineeringdaily.com

", + "Episodes Title": "Advertiser Trust with Marc Goldberg", + "Episodes Uid": "SED6785444560", + "Episodes Audio File": "be79301bb433e219d35442935474644b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5r7", + "Episodes ID": "edf650fa-e328-11ea-91a2-9fd171856773", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_23_GamingwithEliBrown.mp3", + "Episodes Pubdate Date": "2019-05-23", + "Episodes Summary": "

Gaming is becoming mainstream.

Popular multiplayer games such as Fortnite and Minecraft present players with a massive virtual world to explore, build, and compete within. Turn-based games such as Hearthstone and Magic are breeding a new generation of board game and card game aficionados. Social media networks like Twitch and YouTube have turned gaming into a voyeuristic sport that is outcompeting many physical sports games for attention.

Guilded is a platform for managing gaming teams. On Guilded, there are teams for games like League of Legends, Fortnite, and World of Warcraft. These teams use Guilded to manage calendars, Discord bots, forum software, documents, statistics, and recruiting.

This might sound confusing–why does a gaming team need document management, calendars, and analytics? Are we talking about a video game team or a software company? To understand Guilded, you need to understand the rapidly changing modern gaming ecosystem.

Eli Brown is a founder of Guilded.gg. He joins the show to talk about the world of gaming, its intersection with social media, and the fascinating engineering problems involved in building a platform for gaming teams.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Gaming with Eli Brown", + "Episodes Uid": "SED8845798496", + "Episodes Audio File": "813c40e1f868755eaedd8b81141236ee.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4ri", + "Episodes ID": "f0e6bfca-e328-11ea-91a2-3b6832e8f481", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_19_AWSContainers.mp3", + "Episodes Pubdate Date": "2018-10-19", + "Episodes Summary": "

Deepak Singh is the director of compute services at AWS, where he works on cloud products relating to containers, Linux, and High Performance Computing. In today’s show, Deepak describes how the market for containers and serverless has evolved, and how Amazon thinks about product strategy.

Back in 2014, Docker containers were becoming a popular way to deploy and manage application infrastructure. Containers allowed people to take advantage of their servers in a more economical way. Containers let developers move faster by quickly setting up and tearing down small composable units of software.

As these containers grew in number within software companies, companies started figuring out that they needed tooling to manage and orchestrate all these containers. Infrastructure software companies realized that there would be a big business in providing orchestration software to developers who needed to manage these high volumes of containers. This led to the “container orchestration wars”, in which a variety of companies such as Red Hat, CoreOS, Docker, and Mesosphere all began to offer platforms for managing containerized applications.

During the container orchestration wars, many large enterprises such as banks and telcos resisted picking any specific container orchestration system because there was no clear winner. Enterprises were hesitant to place a large bet on an infrastructure orchestration tool that might go out of fashion.

Amazon had a large number of customers that wanted to orchestrate their containers, but it was unclear how the market for open source container orchestration was going to unfold. Around this time, Amazon created ECS, a closed-source container orchestration system.

In the following years, Kubernetes was released and became the most popular container orchestrator. Amazon released EKS, a managed Kubernetes service. They also released AWS Lambda for running serverless functions and AWS Fargate for spinning up long-lived container instances.

Deepak and I discuss the history of containers at Amazon, but we also discuss how developer preferences are changing towards managed services, and how AWS is able to continually build off of its own tools to build higher and higher level services for developers.

", + "Episodes Title": "AWS Containers with Deepak Singh", + "Episodes Uid": "SED6157593459", + "Episodes Audio File": "abf7420c449417cc75dadd1f31033cca.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5kh", + "Episodes ID": "eea27d80-e328-11ea-91a2-1b473e739a86", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_08_AWSStorage.mp3", + "Episodes Pubdate Date": "2019-04-08", + "Episodes Summary": "

RECENT UPDATES:

FindCollabs $5000 Hackathon Ends Saturday April 15th, 2019

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

A software application requires compute and storage.

Both compute and storage have been abstracted into cloud tools that can be used by developers to build highly available distributed systems. In our previous episode, we explored the compute side. In today’s episode we discuss storage.

Application developers store data in a variety of abstractions. In-memory caches allow for fast lookups. Relational databases allow for efficient retrieval of well-structured tables. NoSQL databases allow for retrieval of documents that may have a less defined schema. File storage systems allow the access pattern of nested file systems, like on your laptop. Distributed object storage systems allow for highly durable storage of any data type.

Amazon S3 is a distributed object storage system with a wide spectrum of use cases. S3 is used for media file storage, archiving of log files, and data lake applications. S3 functionality has increased over the years, developing different tiers of data retrieval latency and cost structure. AWS S3 Glacier allows for long-term storage of data at a large cost reduction, in exchange for increased latency of data access.

Kevin Miller is the general manager of Amazon Glacier at Amazon Web Services. He joins the show to talk about the history of storage, the different options for storage in the cloud, and the design of S3 Glacier.

", + "Episodes Title": "AWS Storage with Kevin Miller", + "Episodes Uid": "SED6224808308", + "Episodes Audio File": "ae3016db5badf27821df1feb09744d97.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2b6", + "Episodes ID": "0fb6e0a6-e329-11ea-91a2-5b783b89a2a6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/swpodcasting_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-11-30", + "Episodes Summary": "

Four years ago, I started volunteering for a popular podcast about software–Software Engineering Radio. For the next two years, I learned about the process of making a quality podcast about engineering. With its emphasis on preparation, timeless engineering principles, and attention to the listener, Software Engineering Radio continues to be one of the most popular shows about engineering.

Software Engineering Daily is my effort to bring the quality of SE Radio on a daily basis. In today’s show, I talk to Robert Blumen, the editor of Software Engineering Radio. Robert is responsible for guiding SE Radio, and without my experience producing shows alongside him, Software Engineering Daily probably wouldn’t exist.

If you listen to SE Daily, you should definitely subscribe to SE Radio. I still produce content for SE Radio because the process and the community help me get internal feedback.

", + "Episodes Title": "Software Podcasting with Robert Blumen", + "Episodes Uid": "SED5238897776", + "Episodes Audio File": "0bc28bf991d21e4616b61534ae91b919.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3fk", + "Episodes ID": "f4aa973a-e328-11ea-91a2-77219be7c34f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_23_Speechboard.mp3", + "Episodes Pubdate Date": "2018-01-23", + "Episodes Summary": "

Creating a podcast is still too difficult. One of the main barriers to entry is the editing process. After recording a podcast, the podcast producer needs to line up soundwaves in a digital audio workstation and clip the raw audio files to remove sections that need to be removed. As someone who has edited a lot of podcasts, I know that this is difficult and tedious.

One way of simplifying the editing process is to use speech-to-text to produce a transcription of an audio file, and aligning the text output with the audio. After that alignment, you have a mapping between the text and the audio–so you can delete text and have the corresponding audio be deleted as well.

SpeechBoard is a project by Craig Cannon and Ramon Recuero Moreno. SpeechBoard is an easy way to edit podcasts by deleting transcribed words that are mapped to an audio interview. In this episode, Craig, Ramon and I discuss how SpeechBoard is built and why this product hasn’t existed until recently. We also discuss the podcast world, which Craig is deeply familiar with as the host of Y-Combinator’s podcast. The YC podcast is one of my favorite shows, and if you like SE Daily, you will probably like the YC podcast, so check it out.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "SpeechBoard with Craig Cannon and Ramon Recuero Moreno", + "Episodes Uid": "SED4128494990", + "Episodes Audio File": "ae4aa27937324ff5a777a2d381568d7c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3r2", + "Episodes ID": "f315e294-e328-11ea-91a2-9f563d88b332", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_14_CloudNativeComputingFoundation.mp3", + "Episodes Pubdate Date": "2018-05-14", + "Episodes Summary": "

The Kubernetes ecosystem consists of enterprises, vendors, open source projects, and individual engineers. The Cloud Native Computing Foundation was created to balance the interests of all the different groups within the cloud native community.

CNCF has similarities to the Linux Foundation and the Apache Foundation. CNCF helps to guide open source projects in the Kubernetes ecosystem–including Prometheus, Fluentd, and Envoy. With the help of the CNCF, these projects can find common ground where possible.

KubeCon is a conference organized by the Cloud Native Computing Foundation. I attended the most recent KubeCon in Copenhagen. KubeCon was a remarkably well-run conference–and the attendees were excited and optimistic. As much traction as Kubernetes has, it is still very early days and it was fun to talk to people and forecast what the future might bring.

At KubeCon, I sat down with Chris Aniszczyk and Dan Kohn, who are the COO and director of the CNCF.  I was curious about how to scale an organization like the CNCF. In some ways, it is like scaling a government. Kubernetes is growing faster than Linux grew, and the applications of Kubernetes are as numerous as those of Linux.

Different constituencies want different things out of Kubernetes–and as those constituencies rapidly grow in number, how do you maintain diplomacy among competing interests? It’s not an easy task, and that diplomacy has been established by keeping in mind lessons from previous open source projects.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cloud Native Computing Foundation with Chris Aniszczyk and Dan Kohn", + "Episodes Uid": "SED1056258526", + "Episodes Audio File": "16388fbbfbe112ba1bcc3c72cc820f08.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xf", + "Episodes ID": "ed424682-e328-11ea-91a2-8f827da21675", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_12_Meltano.mp3", + "Episodes Pubdate Date": "2019-07-12", + "Episodes Summary": "

Data engineering allows a company to take advantage of the large quantities of data that the company has generated. In many companies, new data has been produced rapidly for many years, but the company has not been able to take full advantage of it. 

Creating large data sets does not provide immediate value for a company. A company needs to perform data engineering and data science to take full advantage of it.

When data gets generated, it is stored in a database, data lake, or API backend like Google Analytics. In order to manipulate that data, it is often pulled into a data warehouse. A data warehouse provides fast access time to large quantities of data.

Pulling data from a source like a database or data lake into a data warehouse requires a process known as extract and load. Once the data is in the data warehouse, it may also undergo a transform, which enriches the data or puts it in a format that is easier to make use of. Once data is in a data warehouse, it can be used to build models, interactive dashboards, and Jupyter Notebooks.

The data engineering lifecycle has many different components, which is why data engineering can often be intimidating to a company that is trying to make use of their data. Meltano is a project with the goal of providing a system of conventions for managing the data engineering lifecycle. Meltano was started by GitLab, and the Meltano project has some strategic similarities to GitLab.

Danielle Morill is the general manager of Meltano at GitLab. She joins the show to discuss the world of data engineering, and the architecture of Meltano. We touch on the different components of a data engineering pipeline, and the most acute pain points for data engineers.

", + "Episodes Title": "Meltano: Data Engineering Lifecycle with Danielle Morrill", + "Episodes Uid": "SED2507087567", + "Episodes Audio File": "7e3059f1b9f97728ea0b1e798f5c0036.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5lq", + "Episodes ID": "ee85b04c-e328-11ea-91a2-775d0d393d26", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_15_ProteinDeepLearning.mp3", + "Episodes Pubdate Date": "2019-04-15", + "Episodes Summary": "

RECENT UPDATES:

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

FindCollabs Hackathon has ended–winners will probably be announced by the time this episode airs; we will be announcing our next hackathon in a few weeks, so stay tuned

Until Google DeepMind came into the field, protein structure prediction was dominated by academics.

Protein structure prediction is the process of predicting how a protein will fold by looking at genetic code. Protein structure prediction is a perfect field to approach through the application of deep learning, because the inputs are highly dimensional and there is a plentiful array of different sets of labeled data. Protein structure deep learning is a field in which many different approaches are taken, often involving supervised learning and reinforcement learning.

Mohammed Al Quraishi is a systems biologist at Harvard. His background spans computer engineering, statistics, and genetics. In his work, Mohammed explores the interplay between biology and computer systems.

One area of Mohammed’s focus is protein structure prediction. In a blog post last year, Mohammed gave a brief history of protein structure prediction and described the significance of DeepMind entering the field. DeepMind’s AlphaFold technology surpassed all other competitors in the most recent CASP protein structure competition.

Mohammed joins the show to discuss biology, academia, deep learning, and DeepMind.

", + "Episodes Title": "Protein Structure Deep Learning with Mohammed Al Quraishi", + "Episodes Uid": "SED6795816191", + "Episodes Audio File": "3595fd239922ab347d63783bf2081171.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4os", + "Episodes ID": "f1075abe-e328-11ea-91a2-036ff2020921", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_10_Mapillary.mp3", + "Episodes Pubdate Date": "2018-10-10", + "Episodes Summary": "

Mapillary is a platform for gathering photos taken by smartphones and using that data to build a 3D model of the world. Mapillary’s model of the world includes labeled objects such as traffic signs, trees, humans, and buildings. This 3D model can be explored much like you can explore Google Street view.

The data set that underlies Mapillary is crowdsourced from volunteer users who are taking pictures from different vantage points. These smartphone photos are uploaded to Mapillary, queued, and processed to constantly update and refine the Mapillary model.

Mapillary processes high volumes of photos from around the world. The images in these photos need to be correctly fit into Mapillary’s model of the world like a puzzle piece sliding into place. The image needs to be segmented into the different entities within, and those entities need to be put through object recognition algorithm. When two pictures have a conflict, that conflict needs to be resolved.

Mapillary is full of interesting engineering problems. The high volume of images and the level of processing has created the need for a unique sequence of indexing, queueing, and distributed processing using Apache Storm. In addition to processing all of this data and building a 3-D model, Mapillary serves an API for querying geolocations about traffic signs, road conditions, and bus stops.

Peter Neubauer is the co-founder of Mapillary, and is also a co-founder of Neo Technology, the company behind Neo4j. Peter is a world-class engineer and he joins the show to give a detailed overview of the technology behind Mapillary, from ingressing the photos to running data engineering jobs to serving the API.

", + "Episodes Title": "Mapillary: Computer Vision Crowdsourcing with Peter Neubauer", + "Episodes Uid": "SED7557953210", + "Episodes Audio File": "e11ff4ecd2637798ab27acf7e3a58e17.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2v5", + "Episodes ID": "f74be1d8-e328-11ea-91a2-bbe62284c602", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CoinbaseSecurity.mp3", + "Episodes Pubdate Date": "2017-07-14", + "Episodes Summary": "

At Coinbase, security is more important than anything else. Coinbase is a company that allows for storage and exchange of cryptocurrencies. Protecting banking infrastructure is difficult, but in some ways the stakes are higher with Coinbase, because bitcoin is fundamentally unregulated.

If a hacker were able to syphon all of the money out of Coinbase accounts, Coinbase would have no recourse–which means this is a more sensitive problem than the regulated banking system, where transactions can often be reversed.

Philip Martin is the director of security at Coinbase. He joins the show today to explain why his love of complex and high-stakes security challenges brought him to Coinbase. Philip has some specific points about Coinbase and some more abstract points about security that were very useful to me.

This is the third and final episode in our series about Coinbase. Our first two episodes covered the currencies of Coinbase and the fraud prevention techniques the company uses. We’d love to hear your thoughts on this series, and any other suggestions or feedback you have. Send me an email–jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Coinbase Security with Philip Martin", + "Episodes Uid": "SED8123274646", + "Episodes Audio File": "0690c335aecbaa2500ccc20db63ad0d2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "34r", + "Episodes ID": "f60da3ba-e328-11ea-91a2-d39cdeaad9bb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ScalaNative.mp3", + "Episodes Pubdate Date": "2017-10-16", + "Episodes Summary": "

Scala is a functional and object oriented programming language built on the JVM. Scala Native takes this language, loved by many, and brings it to bare metal. Scala Native is an optimizing ahead-of-time compiler and lightweight managed runtime designed specifically for Scala.

Denys Shabalin (dennis shuh-blin) is a Research Assistant at the EPFL and the primary creator of Scala Native. In this episode, Adam Bell interviews Denys about the motivations behind the Scala Native project, how it was implemented and future directions. He also briefly touches on how Scala Native made cold compilation times of Scala code twice as fast. If you are interested in functional programming, compiler design, or want to learn some interesting tidbits about garbage collector design and trade offs you will like this episode.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! We are building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend–and more projects are coming soon. If you have ideas for how software engineering media content should be consumed, or if you are interested in contributing code, check out github.com/softwareengineeringdaily, or join our Slack channel (there’s a link on our website)–or send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Scala Native with Denys Shabalin", + "Episodes Uid": "SED7145888092", + "Episodes Audio File": "dde6aa3531cdcbc23d3e27c96c68ebf7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 339, + "Episodes ID": "f63c4b8e-e328-11ea-91a2-0bdf38cf7e88", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ReactVR.mp3", + "Episodes Pubdate Date": "2017-10-02", + "Episodes Summary": "

React is a programming model for user interfaces. ReactJS is for building user interfaces for web applications. React Native is for building UI on Android or iOS. ReactVR is for building user interfaces in virtual reality.

React Native was originally developed to make it easier to maintain parity between the web, iOS, and Android teams at Facebook. If I build an application for the web with ReactJS, I can rewrite that application for React Native on iOS or Android and reuse some of my code from the web application. It is not a 1-click level of portability between platforms, but it helps share user interface components between different platforms.

ReactVR brings React development to virtual reality. Andrew Imm is a ReactVR developer at Facebook, and he joins the show to discuss how ReactVR works. We talk about the support for VR in the browser: WebGL, WebVR, and ThreeJS. We also explore some of the key React components that you might use to build an interface in ReactVR, and we wrap up the show by exploring VR more broadly–how consumers use VR today and how they might use it in the near future.

The iOS app is the first project to come out of the Software Engineering Daily Open Source Project. There are more projects on the way, and we are looking for contributors–if you want to help build a better SE Daily experience, check out github.com/softwareengineeringdaily. We are working on an Android app, the iOS app, a recommendation system, and a web frontend. Help us build a new way to consume software engineering content at github.com/softwareengineeringdaily.

", + "Episodes Title": "ReactVR with Andrew Imm", + "Episodes Uid": "SED4866467154", + "Episodes Audio File": "341c8cf2fbb0d4b3ec16fd7e8301cc03.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ar", + "Episodes ID": "ef81afdc-e328-11ea-91a2-df07dbac5542", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_05_RocksDB.mp3", + "Episodes Pubdate Date": "2019-02-05", + "Episodes Summary": "

RocksDB is a storage engine based on the log structured merge tree data structure. RocksDB was developed at Facebook to provide a tool for embedded databases. The code for RocksDB is a fork of LevelDB, an embedded database built by Google for the Chrome browser.

Every database has a storage engine. The storage engine is the low level data structure that manages the data in the database. RocksDB is widely used in database applications where a log structured merge tree is preferable to a b-tree. These tend to be write-heavy workloads.

In past shows, we have explored applications of RocksDB in our coverage of databases like TiDB, data intensive applications like Smyte, and data platforms like Rockset. In today’s episode, Dhruba Borthakur and Igor Canadi join for a deep dive into how RocksDB works. Dhruba was the original creator of RocksDB, and Igor is a former Facebook engineer who worked on RocksDB in its early days. Both Dhruba and Igor work at Rockset.

We talk about the log structured merge tree, discuss why an LSM has higher write throughput than storage engines based on a b-tree, and evaluate some of the use cases for RocksDB.

", + "Episodes Title": "RocksDB with Dhruba Borthakur and Igor Canadi", + "Episodes Uid": "SED1593607774", + "Episodes Audio File": "c01469fad1a963381e9a303a90d0b301.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4lc", + "Episodes ID": "f12f4498-e328-11ea-91a2-d7518168dce2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_28_Prisma.mp3", + "Episodes Pubdate Date": "2018-09-28", + "Episodes Summary": "

GraphQL allows developers to communicate with all of their different data backends through a consistent query interface. A GraphQL query can be translated into queries to MySQL, MongoDB, ElasticSearch, or whatever kind of API or backend is needed to fulfill the GraphQL query. GraphQL users need to set up a GraphQL server to fulfill this query federation.

Prisma is a tool for automatically generating a GraphQL API and serving GraphQL queries. The developer defines a data model and deploys with Prisma. Prisma generates the necessary GraphQL infrastructure to serve queries from the developer’s database. This can allow the developer to get up and running faster than they would setting up GraphQL infrastructure and defining the middleware query layer by hand.

Prisma is an open source project, but it is also a company. The opportunities to build a business around a GraphQL infrastructure layer are numerous.

In recent episodes, we have explored the complexities of the “data platform.” From newer companies like Uber to older companies like Procter and Gamble, engineers are struggling to find and access their data sources. Data engineers and data scientists spend months configuring their infrastructure to connect to BI tools and run distributed queries.

GraphQL could simplify data platforms by providing a unified, standardized layer. At this layer, you could also offer caching, virtual data sets, and crowdsourced queries from across the company.

Soren Bramer Schmidt is the CTO and co-founder of Prisma, and he joins the show to discuss why GraphQL has become so popular, how Prisma works, and the opportunities to build developer tooling around GraphQL.

", + "Episodes Title": "Prisma: GraphQL Infrastructure with Soren Bramer Schmidt", + "Episodes Uid": "SED5512297102", + "Episodes Audio File": "da043fc78296f516b8b52ce5e98ab0cf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "41n", + "Episodes ID": "f27fb72e-e328-11ea-91a2-27f81926ed82", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_25_MonzoBankbuilding.mp3", + "Episodes Pubdate Date": "2018-06-25", + "Episodes Summary": "

When you interact with your bank, it probably feels different than when you interact with a software technology company. That’s because the biggest banks in the world were started before software became such a universally important tool. Their core competency is banking–not consumer software.

Today, most banks make consumer-facing software. But these banks were not founded by engineers. The software development process at a typical bank does not look like the software development process at a software company like Netflix.

Monzo is a digital bank that focuses on high quality engineering. Since it was started in 2015, Monzo has always thought of itself as a software company. This gives it certain advantages over older banks.

Today’s guest Richard Dingwall is an engineer at Monzo, and he joins the show to describe Monzo’s software architecture, the engineering strategy, and its migration to Kubernetes. Richard has prior experience at several different banks and financial institutions.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Build a Bank: Monzo with Richard Dingwall", + "Episodes Uid": "SED2480468396", + "Episodes Audio File": "acfc0495798c4461b1ee5b62132917c2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3xe", + "Episodes ID": "f2cd04d4-e328-11ea-91a2-232aebda5342", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_04_AIandCompute.mp3", + "Episodes Pubdate Date": "2018-06-04", + "Episodes Summary": "

Applications of artificial intelligence are permeating our everyday lives. We notice it in small ways–improvements to speech recognition; better quality products being recommended to us; cheaper goods and services that have dropped in price because of more intelligent production.

But what can we quantitatively say about the rate at which artificial intelligence is improving? How fast are models advancing? Do the different fields in artificial intelligence all advance together, or are they improving separately from each other? In other words, if the accuracy of a speech recognition model doubles, does that mean that the accuracy of image recognition will double also?

It’s hard to know the answer to these questions.

Machine learning models trained today can consume 300,000 times the amount of compute that could be consumed in 2012. This does not necessarily mean that models are 300,000 times better–these training algorithms could just be less efficient than yesterday’s models, and therefore are consuming more compute.

We can observe from empirical data that models tend to get better with more data. Models also tend to get better with more compute. How much better do they get? That varies from application to application, from speech recognition to language translation. But models do seem to improve with more compute and more data.

Dario Amodei works at OpenAI, where he leads the AI safety team. In a post called “AI and Compute,” Dario observed that the consumption of machine learning training runs is increasing exponentially–doubling every 3.5 months. In this episode, Dario discusses the implications of increased consumption of compute in the training process.

Dario’s focus is AI safety. AI safety encompasses both the prevention of accidents and the prevention of deliberate malicious AI application.

Today, humans are dying in autonomous car crashes–this is an accident. The reward functions of social networks are being exploited by botnets and fake, salacious news–this is malicious. The dangers of AI are already affecting our lives on the axes of accidents and malice.

There will be more accidents, and more malicious applications–the question is what to do about it. What general strategies can be devised to improve AI safety? After Dario and I talk about the increased consumption of compute by training algorithms, we explore the implications of this increase for safety researchers.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "OpenAI: Compute and Safety with Dario Amodei", + "Episodes Uid": "SED5281448828", + "Episodes Audio File": "3603d8e58b18734ee47f41b56298a08c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5h0", + "Episodes ID": "eee7c1ba-e328-11ea-91a2-47fe7e1a53c3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_18_OSSVenturewithMikeVolpi.mp3", + "Episodes Pubdate Date": "2019-03-18", + "Episodes Summary": "

Red Hat was the first commercial open source software company. For years, investors and entrepreneurs assumed there would never be another Red Hat.

Red Hat’s business was built around enterprise operating system distribution and support. Since the operating system is at the core of how users within a company are doing their job, Red Hat had a lot of leverage and a strong business model. But how many enterprise software products could be so critical to a business that they could manage to offer their software as an open source option yet still make money?

As it turns out, there are many ways to make money in open source.

MySQL ate away at the dominance of Oracle’s database business for similar reasons to Red Hat’s success: much like an operating system, the database layer is critical infrastructure. Cloudera and Hortonworks were able to monetize the open source Hadoop project because Hadoop was hard to deploy and manage.

As cloud infrastructure matured, it became easier to start companies that offered open source software as-a-service. Elastic offers an easy way to use ElasticSearch. RedisLabs offers Redis as a service. MongoDB (the company) offers MongoDB as a service. As it turns out, engineers love to see the source code for databases, but they do not enjoy deploying and managing them and they are happy to pay providers to save them time.

Still, there is continued skepticism of open source businesses.

Today’s debates center around whether individual providers like Elastic can offer a service that competes with an ElasticSearch service offered by AWS. We could just as easily be asking the inverse question– how can AWS compete with an entire company that is dedicated to the deeply technical problem of solving search?

The reality is that most of these open source product categories have an enormous total addressable market, and extremely good unit economics. This applies to both cloud providers and point solution providers. Investors often talk about how much they love subscription businesses. When a company starts purchasing infrastructure-as-a-service from you, it is like they are buying a subscription where the annuity increases over time!

When an investor says they are worried about a giant cloud provider offering the same service as an open source company, it is similar to the investor being worried that a new sales tool is going to be duplicated by Salesforce. The market always needs new sales tools–and the market needs those tools to be offered both by Salesforce and by smaller CRM companies.

In the world of commercial open source, there is plenty of room for both point solution providers and cloud providers. But they are competing for the same customers, and the competitive battlefield is expanding to the nuanced world of software licensing. By changing their licenses, open source projects like Kafka, MongoDB, and Redis can prohibit AWS from certain usage patterns. This might offer some protection for companies based around the point solutions–companies like Confluent and RedisLabs.

Beyond the fracas of the battle between cloud providers and point solutions, there are newer open source companies with models that do not fit tightly into any historical business models. HashiCorp makes a suite of differentiated open source tools that have not been seriously contested or offered as a service by cloud providers. GitLab makes an open source platform that is built with monitoring, logging, CI, and code hosting out of the box.

As the world of open source business models expands, more companies will find opportunity in open sourcing the code that runs their products. In many cases, they will find that it strengthens their advantage rather than weakens it. The defensibility of many businesses relies more on data and network effects than the contents of the codebase. We may see the default question gradually shift from “why should I open source my codebase?” to “why shouldn’t I open source my codebase?”

Mike Volpi is a partner at Index Ventures and has invested in many open source businesses over the last decade. He is on the board of Confluent, Cockroach Labs, Kong, and Elastic. Mike joins the show to share his perspective on open source business models of the past, present, and future.

", + "Episodes Title": "OSS Businesses with Mike Volpi", + "Episodes Uid": "SED2911253845", + "Episodes Audio File": "405d1461fdf7e5f219459d97a2fe2dc6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "54l", + "Episodes ID": "f015677c-e328-11ea-91a2-57887f5aab98", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_20_AdamConrad.mp3", + "Episodes Pubdate Date": "2018-12-20", + "Episodes Summary": "

Ten years ago, there was a distinction between “backend” and “frontend” developers. A backend developer would be managing the business logic and database transactions using Ruby on Rails or Java. A frontend developer would be responsible for implementing designs and arranging buttons using raw HTML and JavaScript.

Today, developers can build entire applications in JavaScript. Developers who spent their early career developing frontend JavaScript skills are finding themselves with a surprising amount of power. With NodeJS providing a backend framework and React, Vue, or Angular on the frontend, a single JavaScript developer can write all the code for a whole application—hence the rise of the “full stack developer”.

At the same time, the cloud infrastructure is becoming easier to use. Backend-as-a-service simplifies the frustrations of deploying your application, and standing up a database. GraphQL improves the relationship between the frontend and the backend. And futuristic technologies like WebAssembly and web virtual reality are promising to make a JavaScript engineer’s life even more interesting.

Adam Conrad is an engineer and a writer for Software Engineering Daily. In recent articles, he has documented the changing nature of the frontend, including JavaScript engines, virtual reality, and how mature corporations are using React and GraphQL. He joins the show to share his perspective on what is changing in the frontend—and how full stack JavaScript engineers can position themselves for future success in a quickly changing market.

", + "Episodes Title": "Modern Front End: React, GraphQL, VR, WebAssembly with Adam Conrad", + "Episodes Uid": "SED6247481894", + "Episodes Audio File": "f6aae5d8a607d40a28507f0d0ef34509.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yc", + "Episodes ID": "f700d77e-e328-11ea-91a2-db101b8cdccf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ServerlessBurningMonk.mp3", + "Episodes Pubdate Date": "2017-08-04", + "Episodes Summary": "

After raising $18 million, social networking startup Yubl made a series of costly mistakes. Yubl hired an army of expensive contractors to build out its iOS and Android apps. Drama at the executive level hurt morale for the full-time employees. Most problematic, the company was bleeding cash due to a massive over-investment in cloud services.

This was the environment in which Yan Cui joined Yubl. The startup did have traction. There were social media stars who would announce on Twitter that they were about to go on Yubl, and Yubl would be hit by an avalanche of traffic. 50,000 users suddenly logging on to interact with their favorite celebrity was a significant traffic spike.

How do you deal with a traffic pattern like that? Serverless computing. AWS Lambda allowed the company to scale up quickly in a cost efficient manner. Yan began refactoring the entire backend infrastructure to be more cost efficient, heavily leveraging AWS Lambda.

Unfortunately, Yan’s valiant effort was not enough to save the company. But there are some incredible engineering lessons from this episode–how to build cost-effective, scalable infrastructure. It’s also a case study worth looking at if you work at a startup, whether or not you are an engineer.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless Startup with Yan Cui", + "Episodes Uid": "SED7047379828", + "Episodes Audio File": "27712a1eb56d6436ac22f77bec1270a3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2m1", + "Episodes ID": "0000b0ec-e329-11ea-91a2-874ae5cc5f2e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/kenyapay_edited_fixed.mp3", + "Episodes Pubdate Date": "2017-04-18", + "Episodes Summary": "

Most people in Africa never had a desktop computer. The first computer they owned was a smart phone. This is why Africa is referred to as a “leap frog” place with regard to computers–Africa leapfrogged the desktop to the smart phone.

The banking system in Africa also followed a trajectory that is different than the West. Westerners are used to banking on their desktop computers. African e-commerce has developed around the smartphone as the computer for banking. As a result, Africa is in a technological development phase with tremendous opportunities in the financial sector and beyond.

Mymookh.com is a Kenyan end-to-end payment platform that allows small- to medium-sized businesses to easily set up online stores and sell to consumers directly from their social media pages. It is one of the many startups across Africa leveraging the accessibility of mobile payments to meet the particular needs of merchants and consumers there. Africa’s development and use of mobile payment systems is expected to grow as more countries on the continent create and adopt this technology.

In this episode, George Gachui, co-founder of Mymookh, talks to Carl Mungazi about how Kenya became a leading player in the mobile payment space with its m-pesa system. He explains how it has revolutionized the way Kenyans approach commerce and payment technology and discusses the challenges of creating a unified platform system that transcends borders and currencies.

Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

", + "Episodes Title": "Kenya Mobile Payments with George Gachui", + "Episodes Uid": "SED9641031151", + "Episodes Audio File": "b1713594dfe113095d4da1d60e79b2d1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2qf", + "Episodes ID": "fb0e6d0e-e328-11ea-91a2-4b5eb0788580", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CassandraShum.mp3", + "Episodes Pubdate Date": "2017-05-22", + "Episodes Summary": "

Many companies are transitioning from a monolith to microservices architecture. Tools for cloud computing, containerization, and continuous delivery are making this easier. But there are still technological and organizational challenges that a company will encounter while making this transition.

Cassandra Shum is an engineer with ThoughtWorks. She has worked with major financial institutions and other large companies to architect their migrations from monolith to microservices. Also, she regularly puts on workshops to engineers who are seeking to make this migration at the company they work at.

In this episode, she describes some of her experiences and recommendations around transitioning from a monolith to microservices.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Microservices Transition with Cassandra Shum", + "Episodes Uid": "SED3026332679", + "Episodes Audio File": "9b3f06cf7bc34be094d260cc2b51982a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4zd", + "Episodes ID": "f06941ee-e328-11ea-91a2-33bfd071fadd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_26_Parity.mp3", + "Episodes Pubdate Date": "2018-11-26", + "Episodes Summary": "

Parity is a company that builds blockchain infrastructure. Parity has built several open source projects and works with enterprises to put blockchain technology in production. Gavin Wood is the founder of Parity, and he joins the show to talk about the state of blockchain technology and what his company is currently focused on. Four years ago, Gavin helped start the Ethereum project, so he has lots of context on decentralized technology.

Gavin envisions a world with many different blockchains for many different use cases. These blockchains will interact with each other to enable trusted relationships between parties. One project that Parity has created is Substrate, a technology that allows developers to quickly stand up a blockchain with the right privacy level. Another project is Polkadot, which allows blockchains to connect and interoperate with each other.

Gavin and I discussed why the world needs a variety of blockchains–and whether all of these different blockchains should need their own cryptocurrency. Gavin described the use case of blockchains for mediating supply chain trust. We also talked about the technologies used to build these projects, including WebAssembly and Rust.

", + "Episodes Title": "Parity: Blockchain Infrastructure with Gavin Wood", + "Episodes Uid": "SED9931319159", + "Episodes Audio File": "9716a4db334c045c11926bb5df6a63c4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 614, + "Episodes ID": "ecd922e2-e328-11ea-91a2-af442ca96ab3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_09_a16zPodcasting.mp3", + "Episodes Pubdate Date": "2019-08-09", + "Episodes Summary": "

The a16z Podcast is a show that is produced by Andreessen Horowitz, an investment fund based in Silicon Valley. The a16z Podcast covers topics including software engineering, biology, media, cryptocurrencies and entrepreneurship. A16z is one of the most popular podcasts about technology.

Sonal Chokshi is the editor in chief at Andreessen Horowitz and the showrunner for the a16z podcast. For five years, she has been interviewing entrepreneurs, engineers, artists, and investors, exploring how software has increasingly impacted our lives and transformed society. 

The success of the a16z Podcast is largely a result of Sonal’s high editorial standards and her ability to ask the right questions and drive conversations in fruitful directions. Much of the content of Software Engineering Daily has been shaped by a16z, and I have listened to every single episode.

Sonal Chokshi joins today’s show for a conversation about podcasting and technology. Sonal shares her beliefs for why the podcast medium has taken off, and describes how her background in education, ethnography, and technology has shaped the completely distinct voice and flavor of the a16z Podcast.

", + "Episodes Title": "a16z Podcasting with Sonal Chokshi", + "Episodes Uid": "SED3195043991", + "Episodes Audio File": "b7d7e6cbaf94e1086934a03f05ba4934.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5aw", + "Episodes ID": "ef7d374a-e328-11ea-91a2-07ef5d9ba3ed", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_06_Cadre.mp3", + "Episodes Pubdate Date": "2019-02-06", + "Episodes Summary": "

Real estate is an asset that is not straightforward to invest in. Real estate can generate excellent returns for investors, but can require much more time and expertise than stocks. Cadre is a company that allows users to invest in real estate more easily and intelligently. Cadre provides users with lots of data about potential investments and enables investments in those opportunities within the platform.

Leonid Movsesyan is the head of engineering at Cadre and joins the show to talk about the problems being solved by the company in areas of product development, infrastructure engineering, hiring, and data science. To build a platform for evaluating real estate investments, Cadre ingests and merges lots of data sets–some public and some private. This gives investors a detailed picture of the value of investments.

Fintech Daily is a new podcast from Software Engineering Daily covering payments, cryptocurrencies, trading, and the intersection of finance and technology. We are looking for volunteer hosts for Fintech Daily, and if you are interested in working with us to conduct interviews, send an email to host@fintechdaily.co. You can find the podcast on iTunes, Google, and everywhere else, and if you are interested in hosting, don’t hesitate to reach out.

", + "Episodes Title": "Cadre: Automated Investing with Leonid Movsesyan", + "Episodes Uid": "SED9594987335", + "Episodes Audio File": "5bed3264b533ca8a003296d1b56c5753.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "58j", + "Episodes ID": "efc5f6a6-e328-11ea-91a2-3340da40a1a3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_15_SlateRobotics.mp3", + "Episodes Pubdate Date": "2019-01-16", + "Episodes Summary": "

Robots are making their way into every area of our lives. Security robots roll around industrial parks at night, monitoring the area for intruders. Amazon robots tirelessly move packages around in warehouses, reducing the time and cost of logistics. Self-driving cars have become a ubiquitous presence in cities like San Francisco.

For a hacker in a dorm room, or a researcher in a small lab, how do you get started with robotics? There are drones and other small options like AWS DeepRacer–but what is the equivalent of the Raspberry Pi for large, human-sized robots?

Zach Allen is the founder of Slate Robotics, a company that makes large, human-sized robots that are at a low enough cost to be accessible to tinkerers, researchers, and prototype builders. Zach joins the show to talk about the state of robotics and why he started a robot company.

What Zach is doing is quite hard–he is a solo founder who has bootstrapped a robotics company from scratch. He is set up in a strip mall in Missouri, where he has set up a row of 3-D printers to create the parts for his robots. He programs and assembles these robots himself.

Whether you are interested in robots are thinking about starting a hardware company, this episode could be useful to you.

", + "Episodes Title": "Human Sized Robots with Zach Allen", + "Episodes Uid": "SED5703870617", + "Episodes Audio File": "2be3795dca6449f2f2510ce7e1cc8a8f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3d9", + "Episodes ID": "f4be7c50-e328-11ea-91a2-cb57d9d53e65", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_17_KubernetesDataNiraj.mp3", + "Episodes Pubdate Date": "2018-01-17", + "Episodes Summary": "

A common problem in a distributed system: how do you take a snapshot of the global state of that system? Snapshot is difficult because you need to tell every node in the system to simultaneously record its state.

There are several reasons to take a snapshot. You might want to take a picture of the global state for the purposes of debugging. Or you might want to take a comprehensive snapshot of your system (including the database) and port your system from one cloud to another. Or you might just need to take a snapshot for disaster recovery.

When a Kubernetes application is deployed, its initial configuration is described in config files. After a deployment, the state of the application might change–some nodes die, some services get scaled up. At any given time, the current state of a Kubernetes cluster is described by etcd, a distributed key-value store.

Niraj Tolia is CEO of Kasten, a company that provides data management, backups, and disaster recovery for Kubernetes applications. Niraj joins the show to describe how Kubernetes deployments manage state, and what the modern business environment is around Kubernetes.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kubernetes State Management with Niraj Tolia", + "Episodes Uid": "SED4754896447", + "Episodes Audio File": "fe217f2d908eca063a8e97103ced91bb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "37n", + "Episodes ID": "f5ad5de8-e328-11ea-91a2-ef367f79490a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/LegalTechnology.mp3", + "Episodes Pubdate Date": "2017-11-10", + "Episodes Summary": "

Imagine that you are a lawyer.

Your work involves managing files with dense, technical text. Your co-workers collaborate with you to accomplish a complex goal that can be broken down into smaller pieces. Your work has formal specifications, but there are degrees of freedom in how you express an idea. In all of these ways, the job of a lawyer is similar to the job of a software engineer–so why don’t lawyers use tools to improve their workflow?

As a software engineer, you have project management tools like Asana that improve collaboration. You have APIs like Stripe that reduce the time spent on a complicated implementation. You have tools like linters and source control that prevent you from making fatal errors. All of these tools save you time.

At many law firms, lawyers do not have incentive to save time. They are paid based on billable hours, not individual milestones. Historically, this hourly billing made sense–lawyers have been around since long before computers. The amount of work that might go into a legal task was hard to predict before you had computers to log data, sort documents, and standardize communications.

In contrast, a software engineer has always had the ability to automate work. That’s why (in most cases) we are not rewarded based on our time spent solving a task. We are paid based on hitting our KPIs and our milestones. With the legacy of hourly billing, lawyers can look at repetitive, administrative tasks as opportunities to make more money.

Justin Kan has been building startups for a decade, and in that time he has interacted with lots of lawyers. From incorporation to fundraising to selling his company Twitch, the interactions with lawyers consistently seemed less transparent and less efficient than would be optimal.

For an engineer like Justin, the natural inclination here was to build software and sell it to lawyers. But there would be so much resistance–you would have to convince the lawyers to change their pricing model to fixed-pricing, which would give them the incentive to buy software and work more efficiently.

Instead, Justin teamed up with a few entrepreneurial lawyers who were willing to start a new law firm from scratch, and use software on day 1. The software company is called Atrium Legal Technology Services (or Atrium LTS for short), and the law firm that uses the software is Atrium LLP. Both of these companies are very new, and were publicly announced a few months ago.

The two companies work side-by-side in undecorated office in downtown San Francisco. When I took the elevator up to see the company, the elevator doors opened and revealed two paper signs pointing to opposite ends of the office. On the Atrium LTS side of the office, engineers were writing software to extract the meaning from documents.

Today, lawyers at old law firms are paid hundreds of dollars an hour to fill in document templates by editing a text document. As the Atrium LTS software gets better, document preparation will be done through web applications, with the variable names disambiguated from the parts of the document that never change from client to client.

On the other side of the office sat Atrium LLP. The legal team was dressed a little more formally than their engineer counterparts, but there was nothing close to the formality of a traditional Silicon Valley law firm. Far from the decor of a Menlo Park law firm, the office space was actually more spartan than most well-funded startups, signaling to the employees that this is an unproven business strategy, and there is a ton of work to be done to validate it.

This sentiment was echoed in my conversation with Justin. It’s possible (even plausible) that Atrium LLP could become the biggest law firm in the world, but the road to getting there will take patience and steady execution. I enjoyed hearing Justin explain the motivation for starting Atrium LTS, and look forward to covering the company in the future.

We have done several other shows about the intersection of software engineering and law, including our show dissecting software antitrust with law professor Harry First.  To find our old episodes, you can download the free Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes.

With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Shout out to today’s featured contributor Craig Holliday. Craig has worked on the Software Engineering Daily iOS app to iron out performance issues and implement features like 2x playback. Big thanks to Craig.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Legal Technology with Justin Kan", + "Episodes Uid": "SED5747439742", + "Episodes Audio File": "f729643e0b4baa488a9576df2d359d7e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4oh", + "Episodes ID": "f10bd152-e328-11ea-91a2-cf395d4b8ce9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_09_DigitalPrivacy.mp3", + "Episodes Pubdate Date": "2018-10-09", + "Episodes Summary": "

When Aran Khanna was a college student, he accepted an internship to work at Facebook.

Even before his internship started, he started playing around with Facebook’s APIs and applications. Aran built a Chrome extension called Marauder’s Map, which used Facebook Messenger’s web APIs to track where people lived, what their schedule was, and other highly sensitive information. These were not public features of Messenger, but Aran was able to reverse engineer the APIs.

As a result, of making Marauder’s Map, Aran’s invitation to work at Facebook was retracted. Aran remained curious about the norms of publicly available social network data, and the second order data sets that could be built on top. Out of this curiosity, Aran created a tool called Money Trail, which used public Venmo data to model a graph of how users were paying each other. Aran showed for a second time that data that seems innocent to share can be repurposed to identify, classify, and incriminate users.

Developers of these online applications face tradeoffs between privacy, convenience, and security. By interacting with these applications, we generate data that suggests how we think, what we like to do, and who we are affiliating with. Google and Facebook probably understand you better than you understand yourself.

Aran Khanna previously was on the show to talk about machine learning at the edge. At the time he worked at Amazon Web Services. He now works as a digital privacy researcher. His background in machine learning makes him well-equipped to talk through the subtleties of modern digital privacy. In this show, Aran returns to talk through the finer points of privacy, data, and artificial intelligence.

", + "Episodes Title": "Digital Privacy with Aran Khanna", + "Episodes Uid": "SED8294711312", + "Episodes Audio File": "4aaac3b110521a08e2f5f3a6ea9af122.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4bq", + "Episodes ID": "f1a17112-e328-11ea-91a2-0ba15f7d2879", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_22_FoodSharing.mp3", + "Episodes Pubdate Date": "2018-08-21", + "Episodes Summary": "

Food gets thrown away from restaurants, homes, catering companies, and any other place with a kitchen. Most of this food gets thrown away when it is still edible, and could provide nutrition to someone who is hungry. Just like Airbnb makes use of excess living capacity, OLIO was started to connect excess food with people who want to eat that food.

There are numerous challenges with this idea. How do you control quality and ensure the food is safe? How do you make money as a business? How do you solve the chicken and egg problem, and make sure that you get hungry users and people with food to give away at the same time?

Lloyd Watkin is a software engineer at OLIO, and he joins today’s episode to describe how the platform works, how it is built, and how the company plans to scale their large base of volunteers. It’s a fascinating set of operational and engineering issues.

", + "Episodes Title": "OLIO: Food Sharing with Lloyd Watkin", + "Episodes Uid": "SED6375322645", + "Episodes Audio File": "e46488d13b32e08732c114c2a136c4dc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "56q", + "Episodes ID": "efe23456-e328-11ea-91a2-474c7551be4d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_08_Multicloud_Ben_Hindman.mp3", + "Episodes Pubdate Date": "2019-01-08", + "Episodes Summary": "

Most applications today are either deployed to on-premise environments or deployed to a single cloud provider.

Developers who are deploying on-prem struggle to set up complicated open source tools like Kafka and Hadoop. Developers who are deploying to a cloud provider tend to stay within that specific cloud provider, because moving between different clouds and integrating services across clouds adds complexity.

Ben Hindman started the Apache Mesos project when he was working in the Berkeley AMPLab. Mesos is a scheduler for resources in a distributed system, allowing compute and storage to be scheduled onto jobs that can use those resources. In his time at the AMPLab, Ben collaborated with Matei Zaharia, creator of Apache Spark.

Ben founded Mesosphere based off of his work on Apache Mesos, and since 2013 he has been building a company to bring it to market. In the meantime, several market forces have influenced the enterprise market.

Enterprise businesses built on virtual machines and on-prem hardware are trying to migrate to containers, Kubernetes, and Spark. Cloud providers like Google and Microsoft have risen to prominence in addition to Amazon’s continued growth, and enterprises are increasingly willing to adopt multiple clouds.

I spoke with Ben Hindman at Kubecon North America. Today, the company that he co-founded works to provide tools for managing these changes in infrastructure. In our conversation, we talked about the necessary mindset shifts for taking a research project and turning it into a highly successful product. We also talked about the newer trends in infrastructure–why enterprises will want multicloud deployments and how serverless APIs and backends will make the lives of developers much easier.

", + "Episodes Title": "Multicloud with Ben Hindman", + "Episodes Uid": "SED4791555402", + "Episodes Audio File": "ecd920b98284a1835fd8a6adbbfe7c56.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 529, + "Episodes ID": "f0400432-e328-11ea-91a2-4363dfca9ed6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_07_Amplify.mp3", + "Episodes Pubdate Date": "2018-12-07", + "Episodes Summary": "

Robotics, genomics, and backend infrastructure: as an in
\nvestor, it can be difficult to assess the viability of a startup that is on the cutting edge in any of these areas.

A robotics startup requires a team with an integrated understanding of hardware and software. A genomics company will not only have to develop a successful healthcare product, but will have to bring it to market through regulation. And in the world of backend infrastructure, building a business that will be differentiated from giant cloud providers gets harder every day.

Amplify Partners is a venture capital fund with an emphasis on technical investments. Their portfolio includes infrastructure companies like Datadog and Gremlin, as well as pharmaceutical and hardware companies.

Sunil Dhaliwal is the founder of Amplify Partners, and joins the show to discuss the thesis of Amplify. The investments that Amplify makes are in technical companies–which makes these financing decisions complex enough to require detailed, individualized research. But there are commonalities among the founding teams. Sunil lays out a useful rubric for anyone who is looking to learn about venture capital investing.

", + "Episodes Title": "Technical Investing with Sunil Dhaliwal", + "Episodes Uid": "SED3789137836", + "Episodes Audio File": "d07689ca224043e9d51931c135ae6dba.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yr", + "Episodes ID": "f6a805a4-e328-11ea-91a2-db9f3c603a4f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Lendup.mp3", + "Episodes Pubdate Date": "2017-08-31", + "Episodes Summary": "

Loans give people more financial security. If people know that they can receive a loan, they will be more willing to take intelligent risks. A loan can allow for a short-term investment that pays off enough to justify the interest rate on that loan.

For the lender, a loan can be a fantastic return on capital–as long as the lendee does not default. When banks were the rulers of the financial infrastructure, most of them would err on the side of caution when it came to lending. They would adhere strictly to credit scores, and a wanting customer would be out of luck if they did not have a credit score, or if their credit score had gotten lower than acceptable.

Newer fintech companies are taking advantage of data sources other than credit scores. They are using machine learning in conjunction with these new data sources to find viable lendees who would be overlooked by traditional institutions.

Ofer Mendelevitch is the VP of data science at LendUp. He joins the show to explain why loans are important, how LendUp functions, and the machine learning systems that power an intelligent system of lending.

", + "Episodes Title": "Lending Machine Learning with Ofer Mendelevitch", + "Episodes Uid": "SED8551077694", + "Episodes Audio File": "a9b12ac6cf0bd2548c612f567845530b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2sb", + "Episodes ID": "f9df6758-e328-11ea-91a2-ab91356b520a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/containerengines.mp3", + "Episodes Pubdate Date": "2017-06-08", + "Episodes Summary": "

Kubernetes makes it easier for engineering teams to manage their distributed systems architecture. But it’s still not simple to deploy and operate a Kubernetes cluster. Google Container Engine (GKE) is a managed control plane for Kubernetes. Just as developers can use Google App Engine to easily deploy monolithic apps against a platform as a service, we can use Google Container Engine to deploy microservices against a platform as a service.

David Aronchick and Chen Goldberg work on Google Container Engine, and they join the show to explain why platform as a service container engines are useful. Google is not the only cloud provider with a container engine–Amazon ECS and Azure Container Engine also allow you to run containers in a managed fashion.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Container Engines with David Aronchick and Chen Goldberg", + "Episodes Uid": "SED9986979942", + "Episodes Audio File": "f915dfeceb298bbe2b4c75b4ff252032.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48x", + "Episodes ID": "f210096a-e328-11ea-91a2-43584ec7de95", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_27_ReactNativeatAirbnb.mp3", + "Episodes Pubdate Date": "2018-07-27", + "Episodes Summary": "

React Native allows developers to reuse frontend code between mobile platforms. A user interface component written in React Native can be used in both iOS and Android codebases. Since React Native allows for code reuse, this can save time for developers, in contrast to a model where completely separate teams have to create frontend logic for iOS and Android.

React Native was created at Facebook. Facebook itself uses React Native for mobile development, and contributes heavily to the open source React Native repository.

In 2016, Airbnb started using React Native in a significant portion of their mobile codebase. Over the next two years, Airbnb saw the advantages and the disadvantages of adopting the cross platform, JavaScript based system. After those two years, the engineering management at Airbnb came to the conclusion to stop using React Native. Gabriel Peal is an engineer at Airbnb who was part of the decision to move off of React Native. Gabriel wrote a blog post giving the backstory for React Native at Airbnb, and he joins the show to give more detail on the decision.

", + "Episodes Title": "React Native at Airbnb with Gabriel Peal", + "Episodes Uid": "SED8807750463", + "Episodes Audio File": "2f63b138793ab46ecb58b3768a35d3fc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5j1", + "Episodes ID": "eeb065b2-e328-11ea-91a2-f73b4eb674d5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/MakerDAO.mp3", + "Episodes Pubdate Date": "2019-04-03", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

A currency can fulfill numerous financial use cases.

One use case is store of value: currency holders can reliably expect their currency to maintain some value, though that value may fluctuate over time. Another use case is speculation: currency holders are owning currency in the hope that the market price of the currency will increase over time.

Bitcoin is a useful store of value and an instrument for speculation. However, Bitcoin still does not fulfill the financial use case that most people need from a currency: price stability. The price of Bitcoin fluctuates rapidly, making it difficult to use Bitcoin for small purchases such as coffee.

Imagine you want to buy a cup of coffee with Bitcoin. The coffee shop owner needs to offer the option to sell you that cup of coffee using Bitcoin as the medium of exchange. This owner must denominate the price of that coffee as some number of Bitcoin. Since the price of Bitcoin fluctuates so rapidly, the coffee shop owner needs to adjust the price of that cup of coffee constantly in order to make sure that the coffee is cheap enough for the consumer to want to buy it, but expensive enough to make a profit.

It is hard to assign prices to market goods in terms of Bitcoin because the currency is in constant flux. Even though many of us would like to use Bitcoin in our everyday lives, most marketplaces are denominated in US dollars or other currencies because a marketplace needs a stable currency in order to operate.

Rune Christensen is the CEO of MakerDAO, a system that provides a price-stable cryptocurrency. MakerDAO is an elegant set of currencies, collateralized debt, smart contracts, and other incentive tools that result in the creation of several transparent, decentralized financial instruments.

Rune joins the show to talk about the importance of stablecoins and how MakerDAO has engineered a decentralized currency that has maintained stability even through tumultuous market conditions.

", + "Episodes Title": "Stablecoins with Rune Christensen", + "Episodes Uid": "SED6323715763", + "Episodes Audio File": "c46a29d515daf5dc37375193dab778ec.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5u6", + "Episodes ID": "ed98f518-e328-11ea-91a2-536264bc4ee6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_20_WasmCompilation.mp3", + "Episodes Pubdate Date": "2019-06-20", + "Episodes Summary": "

WebAssembly allows for web-based execution of languages other than JavaScript. Programs written in Rust or C++ can be compiled down to WebAssembly and shipped over the browser for on-the-fly execution in a safe, memory controlled environment.

WebAssembly has been in development for more than two years, and is still an immature ecosystem because building the necessary tooling for WebAssembly is hard.

Much of the web has been built around JavaScript and the V8 JavaScript engine, which has been tuned to optimize an interpreted language (JavaScript). WebAssembly modules are often written in C++ or Rust, which are compiled languages. There are engineering challenges at the edge between the interpreted JavaScript runtime and the precompiled WebAssembly modules.

Till Schneidereit is a senior research engineering manager at Mozilla. He joins the show to discuss the compilation path of WebAssembly and the state of the ecosystem.

", + "Episodes Title": "WebAssembly Compilation with Till Schneidereit", + "Episodes Uid": "SED2059052856", + "Episodes Audio File": "c00280a0621ac5a3f1631898ba058e49.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4jv", + "Episodes ID": "f13c37b6-e328-11ea-91a2-b38cb54699ce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_25_UnityAR.mp3", + "Episodes Pubdate Date": "2018-09-25", + "Episodes Summary": "

Unity is a game engine for building 2-D and 3-D experiences, augmented reality, movies, and other applications. Unity is cross-platform, so that applications can be written once and deployed to iOS, Android, web, and other surfaces. Unity has been around for 13 years, and has grown in popularity with the rise in gaming and game development.

Brett Bibby is VP of engineering at Unity, and he joins the show to describe how Unity applications are built. Since Unity SDKs allow Unity code to run across all the different platforms, this requires writing and maintaining native code libraries for each of these devices.

When asm.js came out, Unity developers were able to deploy 3-D games to the web–these were some of the first examples of asm.js being used. Asm.js is a small, performant subset of JavaScript that other languages could compile down into. So in this case, Unity programs in C# were running in the browser after being compiled down into asm.js. Since then, WebAssembly has improved the tooling further, allowing a high-performance compilation path for non-JavaScript programs.

After exploring the basics of Unity, Brett described how Unity works with WebAssembly, and the potential for creative applications of Unity both on and off the web.

", + "Episodes Title": "Unity and WebAssembly with Brett Bibby", + "Episodes Uid": "SED5280956105", + "Episodes Audio File": "c7550182e3a81ce0b9f850489895afb6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4io", + "Episodes ID": "f1454932-e328-11ea-91a2-4b2c0a17fd78", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_21_CheckrEngineering.mp3", + "Episodes Pubdate Date": "2018-09-21", + "Episodes Summary": "

Background checks are a routine part of the hiring process. After a potential employee has made it through job interviews, a background check is administered to look through the applicant’s work history, criminal record, and other available data. Conducting a conventional background check can require manual work–including phone calls for reference checks and going to a courthouse to look up physical records of a person’s criminal history.

The on-demand economy has rapidly increased the volume of workers who are getting hired–and all of them need background checks. Lyft drivers, DoorDash food delivery people, Instacart shoppers–these on-demand workers are being trusted with our lives. We get into their cars, let them into our houses, and eat the food that they hand to us. We want some guarantees about their reputation.

Checkr is a background check platform that allows companies to request background check services via API request. Checkr was started 4 years ago, and has benefitted from the growth of gig economy services like ridesharing and food delivery.

Since the background check API product has found success, Checkr has raised additional capital and invested in other new products: a next-generation background check product based on machine learning, and a mobile app that allows people to instantly background check themselves and find jobs that align with the results of that background screening.

Tomas Barreto is the VP of product and engineering at Checkr and he joins the show to describe how the core Checkr API product works, and the challenges of automating the background check process. We also explored the product development roadmap for Checkr, and the product opportunities that come from building within a specialized vertical such as background checks.

", + "Episodes Title": "Checkr: Background Check Platform with Tomas Barreto", + "Episodes Uid": "SED9025175978", + "Episodes Audio File": "b796a08389477624b384c3777fc3065b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 542, + "Episodes ID": "f023b084-e328-11ea-91a2-b727c536ab6b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_16_Mattermost.mp3", + "Episodes Pubdate Date": "2018-12-17", + "Episodes Summary": "

Software companies today rely on group chat applications.

The world of startups and small businesses is dominated by Slack. But for some large enterprises, regulatory constraints prevent them from using Slack. Slack is a web application that is hosted in the cloud, and regulated industries such as banking often need to run their applications on their own on-prem infrastructure.

Mattermost is an open source alternative to Slack that can be self-hosted. This means that all of the networking complexities and scalability challenges that are controlled in the cloud by Slack need to be handled by open source code rather than managed services running in the cloud.

Because it is open source, Mattermost can also be redesigned and customized. Uber designed their own custom version of Mattermost called uChat.

Corey Hulen is a co-founder and the CTO of Mattermost. He joins the show to discuss the motivation for building Mattermost and the engineering challenges of building an open source chat system.

For more episodes about building chat systems, we’ve done several shows about Slack, covering the engineering, security, and chat system.

", + "Episodes Title": "Mattermost: Self-Hosted Slack Alternative with Corey Hulen", + "Episodes Uid": "SED2613536336", + "Episodes Audio File": "9b3238c9fe12f3453ed82f9b59a21abf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "31x", + "Episodes ID": "f68121a0-e328-11ea-91a2-47d17f722ffb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Word2vecAdrianColyer.mp3", + "Episodes Pubdate Date": "2017-09-13", + "Episodes Summary": "

Machines understand the world through mathematical representations. In order to train a machine learning model, we need to describe everything in terms of numbers.  Images, words, and sounds are too abstract for a computer. But a series of numbers is a representation that we can all agree on, whether we are a computer or a human.

In recent shows, we have explored how to train machine learning models to understand images and video. Today, we explore words. You might be thinking–”isn’t a word easy to understand? Can’t you just take the dictionary definition?” A dictionary definition does not capture the richness of a word. Dictionaries do not give you a way to measure similarity between one word and all other words in a given language.

Word2vec is a system for defining words in terms of the words that appear close to that word. For example, the sentence “Howard is sitting in a Starbucks cafe drinking a cup of coffee” gives an obvious indication that the words “cafe,” “cup,” and “coffee” are all related. With enough sentences like that, we can start to understand the entire language.

Adrian Colyer is a venture capitalist with Accel, and blogs about technical topics such as word2vec. We talked about word2vec specifically, and the deep learning space more generally. We also explored how the rapidly improving tools around deep learning are changing the venture investment landscape.

If you like this episode, we have done many other shows about machine learning with guests like Matt Zeiler, the founder of Clarif.ai and Francois Chollet, the creator of Keras. You can check out our back catalog by downloading the Software Engineering Daily app for iOS, where you can listen to all of our old episodes, and easily discover new topics that might interest you. You can upvote the episodes you like and get recommendations based on your listening history. With 600 episodes, it is hard to find the episodes that appeal to you, and we hope the app helps with that.

Question of the Week: What is your favorite continuous delivery or continuous integration tool? Email jeff@softwareengineeringdaily.com and a winner will be chosen at random to receive a Software Engineering Daily hoodie. 

", + "Episodes Title": "Word2Vec with Adrian Colyer", + "Episodes Uid": "SED6924371108", + "Episodes Audio File": "06d6a51c041cc605f4426a1a054dd08e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "65b", + "Episodes ID": "ec88626c-e328-11ea-91a2-bf0bbe28dc63", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_04_Datastax.mp3", + "Episodes Pubdate Date": "2019-09-04", + "Episodes Summary": "

Cassandra was initially released in 2008 as a project out of Facebook. Cassandra offered an open source solution to database scalability issues that were being tackled internally by large companies like Amazon, Google and Facebook. 2008 was a golden age of new infrastructure, with systems such as Hadoop and Kafka gaining traction around the same time.

Jonathan Ellis started working with Cassandra, and became intrigued by the system. With the help of investors, Jonathan began working on a company based around Cassandra called Datastax. Today, Datastax is a company with more than 450 employees and a large valuation.

Jonathan joins the show to discuss his experience working with Cassandra, and his reflections on the becoming an entrepreneurial founder of a highly successful database company. There is a wealth of useful knowledge for both software engineers and entrepreneurs in this episode.

", + "Episodes Title": "Cassandra Business with Jonathan Ellis", + "Episodes Uid": "SED3074439569", + "Episodes Audio File": "8a899741717f843ed2713617a049fbb1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4j1", + "Episodes ID": "f114bc9a-e328-11ea-91a2-cb25157bcef3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_04_Jaspersoft.mp3", + "Episodes Pubdate Date": "2018-10-06", + "Episodes Summary": "

We previously released this episode with the wrong audio file and are re-releasing it on a weekend.

TIBCO was started in the 90’s with a popular message bus product that was widely used by finance companies, logistics providers, and other systems with high throughput. As TIBCO grew in popularity, the company expanded into other areas through products it developed in-house as well as through acquisitions.

One acquisition was Jaspersoft, a business intelligence data platform. When TIBCO acquired Jaspersoft in 2014, the architecture was a monolithic Java application. Around this time, customer use cases were shifting from centralized reporting to real-time, embedded visualizations.

The use case of the Jaspersoft software was becoming less centralized and less monolithic and the software architecture needed to change in order to reflect that.

Jan Schiffman is a VP of engineering at TIBCO and Sherman Wood is a director at TIBCO. They join the show to discuss the process of migrating a large Java monolith to a composable set of services. Breaking up a monolith is not an easy process–nor is it something that every company should do just because they have a monolith. In some cases, a monolith is just fine.

Jan and Sherman explain why the business use case for why the Jaspersoft monolith needed to be refactored, and their approach to the refactoring. We also talk through the modern use cases of embedded analytics and the interaction between business analysts and data engineers. At a higher level, we discuss the lessons they have learned from managing a large, complex refactoring. Full disclosure: TIBCO is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Monolith Migration with Jan Schiffman and Sherman Wood", + "Episodes Uid": "SED1669713289", + "Episodes Audio File": "d941a52b86f4c56e625b7abbbb92400a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ou", + "Episodes ID": "f3688a62-e328-11ea-91a2-878c43c24c6d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_23_StripeObservability.mp3", + "Episodes Pubdate Date": "2018-04-23", + "Episodes Summary": "

Stripe processes payments for thousands of businesses. A single payment could involve 10 different networked services. If a payment fails, engineers need to be able to diagnose what happened. The root cause could lie in any of those services.

Distributed tracing is used to find the causes of failures and latency within networked services. In a distributed trace, each period of time associated with a request is recorded as a span. The spans can be connected together because they share a trace ID.

The spans of a distributed trace are one element of observability. Others include metrics and logs. Each of these components of observability make their way into services like Lightstep and Datadog. The path traveled by different elements of observability is called the observability pipeline.

In an episode last year, Cory Watson explained how observability works at Stripe. In today’s episode, Cory describes how observability is created and aggregated. It’s a useful discussion for anyone working at a company that is figuring out how to instrument their systems for better monitoring.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Stripe Observability Pipeline with Cory Watson", + "Episodes Uid": "SED5972385455", + "Episodes Audio File": "b9e5fb17af5171a810f516d2d214b572.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "34e", + "Episodes ID": "f61bb86a-e328-11ea-91a2-9bf536a0b42d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/EthereumBasics.mp3", + "Episodes Pubdate Date": "2017-10-11", + "Episodes Summary": "

Ethereum is a decentralized transaction-based state machine. Ethereum was designed to make smart contracts more usable for developers. Smart contracts are decentralized programs that usually allow for some a transaction between the owner of the contract and anyone who would want to purchase something from the contract owner.

For example, I could set up a smart contract where a listener sends my smart contract some ether and I send the listener a podcast episode automatically. Smart contracts can also interact with each other, to network together complex transactions. In the same way that web development has been made easier by PaaS and SaaS, smart contracts will make building financial systems simple.

Preethi Kasireddy is a blockchain developer who writes extensively about cryptocurrencies. She joins the show to describe how the Ethereum platform works, including the steps involved in a smart contract transaction. This episode covers some advanced topics of Ethereum, and if you are out of your comfort zone, don’t worry–you aren’t alone.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! We are building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend–and more projects are coming soon. If you have ideas for how software engineering media content should be consumed, or if you are interested in contributing code, check out github.com/softwareengineeringdaily, or join our Slack channel (there’s a link on our website)–or send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Ethereum Platform with Preethi Kasireddy", + "Episodes Uid": "SED9506168506", + "Episodes Audio File": "6770c27695378e0834d11d28900d2011.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ra", + "Episodes ID": "edeb8ec2-e328-11ea-91a2-3fc13b670db2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_28_ARhythm.mp3", + "Episodes Pubdate Date": "2019-05-28", + "Episodes Summary": "

Augmented reality applications can be used on smartphones and dedicated AR headsets. On smartphones, ARCore (Google) and ARKit (Apple) allow developers to build for the camera on a user’s smartphone. AR headsets such as Microsoft HoloLens and Magic Leap allow for a futuristic augmented reality headset experience.

The most prominent use of augmented reality today is gaming, with a notable example being Niantic’s Pokemon Go. Tony Godar is a software engineer who works on augmented and virtual reality applications. He joins the show to talk about his day job working on virtual reality experiences, and an AR game he built called ARhythm.

Tony was the winner of the FindCollabs Hackathon and we also discussed his experience working on the project through FindCollabs.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Augmented Reality Gaming with Tony Godar", + "Episodes Uid": "SED7006491420", + "Episodes Audio File": "25e0a3c76ada1cc7d12010453eedd17e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4mi", + "Episodes ID": "f1268ed4-e328-11ea-91a2-4b39973824eb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_02_Kotlin.mp3", + "Episodes Pubdate Date": "2018-10-02", + "Episodes Summary": "

Kotlin is a statically typed programming language that started as a JVM language. It gained popularity because it reduces the amount of boilerplate code required for a typical Java project. Many of the early adopters of Kotlin were building Android apps or Java applications, but it has grown to a variety of use cases including at companies like Uber, Pinterest, and Atlassian.

Andrey Breslav is the lead language designer of Kotlin at JetBrains. He joins the show to describe the original goals of Kotlin, the compilation path of the language, and how it has moved beyond its days of only running on the JVM.

", + "Episodes Title": "Kotlin Design with Andrey Breslav", + "Episodes Uid": "SED8168132092", + "Episodes Audio File": "dc009e2fb1194e95d96d9470762ef809.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "58t", + "Episodes ID": "efbd31b0-e328-11ea-91a2-b7995cf48565", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_18_Spotinst.mp3", + "Episodes Pubdate Date": "2019-01-18", + "Episodes Summary": "

When a developer provisions a cloud server, that server is called an “instance”. These instances can be used for running whatever workload a developer has, whether it is a web application, a database, or a set of containers.

The cloud is cheap to get started on. New applications with few users can often be hosted on infrastructure that is less than $10 per month. But as an application grows in popularity, there is more demand for CPUs and storage. A company will start to buy more and more servers to scale up to the requirements of their growing user base. The costs of running infrastructure in the cloud will increase, and the company will start to look for ways to save money.

One common method of saving money is to buy “spot instances”. A spot instance is an instance that is cheaper than “reserved instances” or “on-demand” instances. The reason that there are different instance types is because a giant cloud provider has a highly variable amount of work that is being demanded from that cloud provider.

If you are in charge of AWS, you have to make sure that at any given time, you can give server resources to anyone that asks for it. Your data centers need to have physical machines that are ready to go at any time. This means that much of the time, you have server resources that are going unused.

If you are a cloud provider, how can you get people to use your compute resources? You can make them cheaper. So a user can come along and buy your compute at the discounted “spot” price.

But this presents a problem for the cloud provider. If you start to give away your compute at cheaper prices, and then the overall demand for your cloud resources go up once again, you are going to miss out on profits. As the cloud provider, you need to kick people off of your spot instances, so that you can take those same instances and sell them to people at the higher market prices.

And this presents a problem for the user. If you buy a cheap spot instance, that instance is only available until the cloud provider decides to kick you off. You have a tradeoff between cost and availability of your instances. Because of this, spot instances are typically used only for workloads that are not mission critical–workloads that can afford to fail.

Spotinst is a company that allows developers to deploy their workloads reliably onto spot instances. Spotinst works by detecting when a spot instance is going to be reclaimed by a cloud provider and re-scheduling the workload from that cloud provider onto a new spot instance.
\nAmiram Shachar is the CEO of Spotinst. He joins the show to talk about the different types of instances across cloud providers, the engineering behind Spotinst, and how the usage of containers and the rise of Kubernetes is changing the business landscape of the cloud.

", + "Episodes Title": "Spot Instances with Amiram Shachar", + "Episodes Uid": "SED5795449797", + "Episodes Audio File": "b82dc202fedbe2c355ad330466b3797a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "50q", + "Episodes ID": "f05b32de-e328-11ea-91a2-5b61006cbe85", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_29_CloudCosts.mp3", + "Episodes Pubdate Date": "2018-11-29", + "Episodes Summary": "

Cloud computing changed the economics of running a software company. Before the cloud, a software company had to purchase physical machines which often required thousands of dollars paid up front. The cloud allowed developers to deploy their applications for free, to operate a business for cheap, and to scale without hiring a dedicated team to manage the servers.

Building in the cloud is cheap, but scaling in the cloud can get expensive. A growing company can often save money by changing which cloud instances and services they use. Reducing the number of server instances, changing the size of compute instances, and changing rules around auto scaling. By using monitoring, dashboards, and regular analysis of where money is spent, a business can find thousands of dollars of wasted spend per month.

There are also broad strategic decisions around cost. One area to study is the use of “managed” services like Amazon DynamoDB, Google BigQuery, and Amazon Lambda. These services are proprietary, and can lead to lock-in. Sometimes they can be quite expensive. But they can save developers hours of time because they are easy to use, and provide high uptime guarantees.

Ran Rothschild works at DoIT International, a company that helps businesses figure out how to save money on their cloud infrastructure. He joins the show to discuss the places where the most money is wasted and how startups can manage their infrastructure in a cost-effective manner. He also tells some stories about significant overspend. Full disclosure: DoIT International is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Cloud Costs with Ran Rothschild", + "Episodes Uid": "SED1580948193", + "Episodes Audio File": "3a57294775c0cfeb0b38863872e2879d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 623, + "Episodes ID": "ecc29a36-e328-11ea-91a2-bba2c1e4ec0e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_15_MoonlightWorkContracting.mp3", + "Episodes Pubdate Date": "2019-08-15", + "Episodes Summary": "

Software engineers often work as a contractor for some duration of their career.

A contractor earns a fixed hourly salary for a defined period of weeks, months, or years. Contract work can be more flexible than full-time work, and often pays more than full-time software engineering, because contract jobs can end at any time, and they do not have the added employee benefits such as health insurance and stock options.

Online contracting platforms such as Upwork and Fiverr have expanded the number of software contracting engagements that take place. Developers on Upwork and Fiverr have a wide range of skills and experience levels. The clients who come on Upwork and Fiverr looking for developers are sometimes unsophisticated at managing software projects, and in some cases they defraud the software developers who are making their living online, and trick these software developers into delivering free work.

Moonlight is a contracting platform for software engineers. Today’s guests Emma Lawson and Philip Thomas are the founders of Moonlight, and they join the show to explain why they started the company, and the gaps that exist in the world of software contracting. Moonlight’s model is different than most other contracting platforms, in that Moonlight requires clients to pay a $300 subscription fee to recruit engineers on the platform. This $300 subscription price lowers the rate at which clients take advantage of software engineers. This dynamic causes the software engineers to take their work more seriously and act more professionally.

Full disclosure: I am an investor in Moonlight. I have also been a paying client of the service, and our newest version of the Software Daily app was built by Mostafa Gazar, who is a talented Android engineer I met on Moonlight.

", + "Episodes Title": "Moonlight: Software Contracting Platform with Emma Lawson and Philip Thomas", + "Episodes Uid": "SED3726124078", + "Episodes Audio File": "9aa7e46ec9f2dc788feb7ea4d8ccc5cb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ik", + "Episodes ID": "054d311a-e329-11ea-91a2-6f3dbfb22b75", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/codepath_edited.mp3", + "Episodes Pubdate Date": "2017-03-07", + "Episodes Summary": "

There is too much mobile engineering work to be done and not enough mobile engineers. As a result, a talented mobile engineer will often make more money than a similarly talented web developer.

There are many other disconnects between the world of mobile engineering and the world of backend and web development.

We have reported on web development far more than mobile on Software Engineering Daily, and, I wanted to get a holistic view of the mobile ecosystem. Nathan Esquenazi is a co-founder of CodePath, which is a continuing education program for professional engineers and designers.

There was much to explore–from the economics of mobile, to the state of cross platform, to the increasingly blurry line between mobile and IoT.

", + "Episodes Title": "Mobile Engineers with Nathan Esquenazi", + "Episodes Uid": "SED5131238636", + "Episodes Audio File": "7189aea5a8353f29b01881a9a42b5c33.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3h0", + "Episodes ID": "f4646832-e328-11ea-91a2-931c9a9d6d9a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_09_GoogleBeyondCorp.mp3", + "Episodes Pubdate Date": "2018-02-09", + "Episodes Summary": "

Employees often find themselves needing to do work outside of the office.

Depending on the sensitivity of your task, accessing internal systems from a remote location may or may not be OK. If you are using a corporate application that shows the menu of your company’s cafe on your smartphone, your workload is less sensitive. If you are accessing the proprietary codebase of your company’s search engine, your workload is more sensitive.

As Google grew in headcount, the different cases of employees logging in from different places grew as well. Google developed a fine-grained, adaptive security model called BeyondCorp to allow for a wide variety of use cases. Whether you are an engineer logging in from a Starbucks or a human resources employee logging in from your desk, the BeyondCorp system uses the same access proxy to determine your permissions.

The BeyondCorp architecture is also built around the assumption of a zero-trust network. A zero-trust network is a modern enterprise security architecture where internal servers do not trust each other.

Zero-trust networks assume that the network has already been breached. If you are writing an internal application, your default assumption should be to distrust an incoming request from someone else on the network.

The zero-trust model is in contrast to an outdated model of enterprise security–that of the hard outer defense of a firewall, that purports to prevent attackers from ever making their way into the vulnerable inside of a network. The firewall model assumes that all of these servers within the firewall can trust each other.

Several papers have come out of Google discussing the BeyondCorp security model. These papers describe the network architecture, and the security philosophies of BeyondCorp.

Since the release of these papers, an ecosystem of security providers has sprung up to provide implementation services for companies that want BeyondCorp security in their enterprise. Google has also productized its BeyondCorp system with an identity-aware proxy that is tied into their Google Cloud product.

Max Saltonstall is the technical director of information technology in the office of the CTO at Google, where he has helped to facilitate the widespread adoption of the BeyondCorp program. In this episode, we talk about enterprise security–from remote employee access to zero-trust networks. We also talk about implementing the BeyondCorp model–why enterprises should consider it, and how to do it.

We have done lots of past shows about security–from car hacking to smart contract vulnerabilities to discussions with luminaries like Bruce Schneier and Peter Warren Singer. To find all of our episodes about security, download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Google BeyondCorp with Max Saltonstall", + "Episodes Uid": "SED7894090519", + "Episodes Audio File": "69a47b1b57496f97be503b303524de35.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 386, + "Episodes ID": "f598741e-e328-11ea-91a2-535452dbed52", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/HighVolumeEventProcessing.mp3", + "Episodes Pubdate Date": "2017-11-16", + "Episodes Summary": "

A popular software application serves billions of user requests. These requests could be for many different things. These requests need to be routed to the correct destination, load balanced across different instances of a service, and queued for processing. Processing a request might require generating a detailed response to the user, or making a write to a database, or the creation of a new file on a file system.

As a software product grows in popularity, it will need to scale these different parts of infrastructure at different rates. You many not need to grow your database cluster at the same pace that you grow the number of load balancers at the front of your infrastructure. Your users might start making 70% of their requests to one specific part of your application, and you might need to scale up the services that power that portion of the infrastructure.

Today’s episode is a case study of a high-volume application: a monitoring platform called Raygun.

Raygun’s software runs on client applications and delivers monitoring data and crash reports back to Raygun’s servers. If I have a podcast player application on my iPhone that runs the Raygun software, and that application crashes, Raygun takes a snapshot of the system state and reports that information along with the exception, so that the developer of that podcast player application can see the full picture of what was going on in the user’s device, along with the exception that triggered the application crash.

Throughout the day, applications all around the world are crashing and sending requests to Rayguns servers. Even when crashes are not occurring, Raygun is receiving monitoring and health data from those applications. Raygun’s infrastructure routes those different types of requests to different services, queues them up, and writes the data to multiple storage layers–ElasticSearch, a relational SQL database, and a custom file server built on top of S3.

John-Daniel Trask is the CEO of Raygun and he joins the show to describe the end-to-end architecture of Raygun’s request processing and storage system. We also explore specific refactoring changes that were made to save costs at the worker layer of the architecture. This is useful memory management strategy for anyone working in a garbage collected language. If you would like to see diagrams that explain the architecture and other technical decisions, the show notes have a video that explains what we talk about in this show. Full disclosure: Raygun is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "High Volume Event Processing with John-Daniel Trask", + "Episodes Uid": "SED6171914084", + "Episodes Audio File": "4d625c02cba853f9c93eefc9eb0a5ebb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "31p", + "Episodes ID": "f68a8326-e328-11ea-91a2-fbfe6911d8dd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SEDApp.mp3", + "Episodes Pubdate Date": "2017-09-08", + "Episodes Summary": "

You have probably missed some of the best episodes of Software Engineering Daily. If you listen to just a few episodes a week, it can be difficult to identify the high quality shows. And if you are new to the podcast, you have no idea how to find episodes that might appeal to you.

Software Engineering Daily has a discovery problem.

We have 600 episodes, and much of the content is evergreen. The shows we did a year ago on Apache Spark, or Ethereum, or ReactJS are still relevant today, and they get plenty of listens.

Keith and Craig Holliday built a recommendation system for Software Engineering Daily. Then they built a Software Engineering Daily iOS app to improve the experience of SE Daily listeners. You can use the SE Daily app to find the most popular episodes of this podcast, and to find episode recommendations based on what you have listened to.

In this episode, Keith and Craig join the show to explain why they built an app for Software Engineering Daily. You can find all the code for the SE Daily app at github.com/softwareengineeringdaily in case you want to fork it for your own podcast–or if you want to contribute to it.

Question of the Week: What is your favorite continuous delivery or continuous integration tool? Email jeff@softwareengineeringdaily.com and a winner will be chosen at random to receive a Software Engineering Daily hoodie. 

", + "Episodes Title": "Software Engineering Daily App with Keith and Craig Holliday", + "Episodes Uid": "SED6296877526", + "Episodes Audio File": "328bbc662f46d48eb5383546ebd7e12a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ys", + "Episodes ID": "f6b148bc-e328-11ea-91a2-0b10add90da1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SalesSoftware.mp3", + "Episodes Pubdate Date": "2017-08-29", + "Episodes Summary": "

Most products do not sell themselves. Salespeople bridge the gap between a product creation and a customer who purchases it.

People can make a good living on the internet selling niche products–if they can find their customers. The process of taking a large group of potential customers and narrowing it down to only the subset of those customers who will buy your product is known as the sales funnel. The sales funnel consists of multiple stages–the first of which is known as “prospecting.”

A salesperson doing prospecting is casting a wide net, sending emails to hundreds or thousands of people, looking for anyone who has some small probability of being interested. Without a tool for prospecting, the process can be very labor intensive.

Jean-Baptise Escoyez is the CTO at Prospect.io, a tool for sales prospecting. In this episode, we explored the process of building Prospect.io, from the high level product design to the engineering details of how it is implemented. I use Prospect.io to sell two different products so it was enjoyable to find out how one of my favorite tools works.

", + "Episodes Title": "Sales Software with Jean-Baptiste Escoyez", + "Episodes Uid": "SED1456758415", + "Episodes Audio File": "e91b87005d3a31d541fc9664d2cd6a7d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3h1", + "Episodes ID": "f4505ec8-e328-11ea-91a2-ff831e152e04", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_15_TugdualGraal.mp3", + "Episodes Pubdate Date": "2018-02-15", + "Episodes Summary": "

At a big enough scale, every software product produces lots of data. Whether you are building an advertising technology company, a social network, or a system for IoT devices, you have thousands of events coming in at a fast pace that you want to aggregate, study and act upon.

For the last decade, engineers have been learning to store and process these vast quantities of data.

The first common technique was to store all your data to HDFS–the Hadoop Distributed File System–and run nightly Hadoop MapReduce jobs across that data. HDFS is cheap (stored on disk), effective (Hadoop had a revolutionary effect on business analysis), and easy to understand (“every night we take all the data from the previous day, analyze it with Hadoop, and send an email report to our analysts”).

The second common technique was the “Lambda Architecture.” The Lambda Architecture used a stream processing system like Apache Storm to process all incoming events as soon as they were created, so that software products could react quickly to the changes occurring in a large scale system. But events would sometimes be processed out of order, or they would get lost due to node failures. To fix those errors, the nightly Hadoop MapReduce jobs would still run, and would reconcile all the problems that might have occurred when the events were processed in the streaming system.

The Lambda Architecture worked pretty well–systems were becoming “real time”, and products like Twitter were starting to feel alive as they were able to rapidly process the massive volume of events on the fly. But managing a system with a Lambda Architecture was painful–you had to manage both a Hadoop cluster and a Storm cluster. You had to make sure that your Hadoop processing did not interfere with your Storm processing.

Today, a newer technique for ingesting and reacting to data has become more common, and is referred to as “streaming analytics.” Streaming analytics is a strategy for performing fast analysis of data coming into a system.

In streaming analytics systems, events are sent to a scalable, durable pubsub system such as Kafka. You can think of Kafka as a huge array of events that have occurred–such as users liking tweets or clicking on ads. Stream processing systems like Apache Flink or Apache Spark read the data from Kafka as if they were reading an array that was being continually appended to.

The sequence of events that get written to Kafka are called “streams”. This can be confusing–with a stream, you imagine this constantly moving, transient sequence of data. That’s partially true, but data will stay in Kafka as long as you want it to. You can set a retention policy for 2 weeks, 2 months, or 2 years. As long as that data is still retained in Kafka, your stream processing system can start reading from any place in the stream.

The stream processing systems like Flink or Spark that read from Kafka are still grabbing batches of data, and processing them in batches. They are reading from the event stream buffer in Kafka, which you can think of as an array. (This is something that confused me for a long time, so if you are still confused, don’t worry, we explain it more in this episode.)

Tugdual Grall is an engineer with MapR. In today’s episode, we explore use cases and architectural patterns for streaming analytics. Full disclosure: MapR is a sponsor of Software Engineering Daily.

In past shows, we have covered data engineering in detail–we’ve looked at Uber’s streaming architecture, talked to Matei Zaharia about the basics of Apache Spark, and explored the history of Hadoop. To find all of our episodes about data engineering , download the Software Engineering Daily app for iOS or Android. These apps have all 650 of our episodes in a searchable format–we have recommendations, categories, related links and discussions around the episodes. It’s all free and also open source–if you are interested in getting involved in our open source community, we have lots of people working on the project and we do our best to be friendly and inviting to new people coming in looking for their first open source project. You can find that project at Github.com/softwareengineeringdaily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Streaming Architecture with Tugdual Grall", + "Episodes Uid": "SED5827428918", + "Episodes Audio File": "b0d3a5688b17c5141e9e8d8f5007742e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "41p", + "Episodes ID": "f2761fe8-e328-11ea-91a2-bf1106ff6286", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_27_ShopifyMigration.mp3", + "Episodes Pubdate Date": "2018-06-27", + "Episodes Summary": "

Shopify runs more than 500,000 small business websites. When Shopify was figuring out how to scale, the engineering teams did not have a standard workflow for how to deploy and manage services. Some teams used AWS, some teams used Heroku, some teams used other infrastructure providers.

To manage all those stores effectively, Shopify has built its own platform-as-a-service on top of Kubernetes called Cloudbuddies. Cloudbuddies was inspired by Heroku, and it allows engineers at Shopify to deploy services in an opinionated way that is perfect for Shopify.

Niko Kurtti is a production engineer at Shopify, and he joins the show to describe Shopify’s infrastructure–how they run so many stores, how they distribute those stores across their infrastructure, and the motivation for building their own internal platform on top of Kubernetes.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Shopify Infrastructure with Niko Kurtti", + "Episodes Uid": "SED4213075655", + "Episodes Audio File": "8422778b1b7909abb4fe3ebce341f026.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ny", + "Episodes ID": "f389d712-e328-11ea-91a2-17dd08cf7d82", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_12_Mastodon.mp3", + "Episodes Pubdate Date": "2018-04-12", + "Episodes Summary": "

Social networks can make you feel connected to a global society. But those social networks are controlled by a corporate entity. The profit motivations of the corporation are not directly aligned with the experience of the users.

Mastodon is an open source, decentralized social network. Eugen Rochko started building Mastodon in response to his dissatisfaction with centralized social networks like Facebook and Twitter. In the Mastodon model, users can run their own nodes, and other users can connect to them. You can follow users whose accounts reside in other nodes.

Eugen joins the show to discuss how Mastodon works, and how its thousands of users interact on the platform. We explore the open source community that is building Mastodon, and speculate on the future of social networks.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Mastodon: Federated Social Network with Eugen Rochko", + "Episodes Uid": "SED6975708920", + "Episodes Audio File": "d4691530cefd38009913bb2b52005be7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3zp", + "Episodes ID": "f2aa5240-e328-11ea-91a2-875bca9ad394", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_13_CitusData.mp3", + "Episodes Pubdate Date": "2018-06-13", + "Episodes Summary": "

Relational databases have been popular since the 1970s, but in the last 20 years the amount of data that applications need to collect and store has skyrocketed. The raw cost to store that data has decreased. There is a common phrase in software companies: “it costs you less to save the data than to throw it away.”

Saving the data is cheap, but accessing that data in a useful way can be expensive. Developers still need rapid row-wise and column-wise access to the data. Accessing an individual row of a database can be useful if a user is logging in and you want to load all of that user’s data, or if you want to update a banking system with a new financial transaction. Accessing an entire column of a database can be useful if you want to aggregate summaries of all of the entries in a system–like the sum of all financial transactions in a bank.

These different kinds of transactions are nothing new, but with the growing scale of data, companies are changing their mentality from thinking in terms of individual databases to thinking about distributed “data platforms.”

In a data platform, the data across a company might be put into a variety of storage systems–distributed file systems, databases, in-memory caches, search indexes–but the API for the developer is kept simple. And the simplest, most commonly understood language is SQL.

Marco Slot is an engineer with Citus Data, a company that makes Postgres scalable. Postgres is one of the most common relational databases, and in this episode Marco describes how Postgres can be used to service almost all of the needs of a data platform.

This isn’t easy to do, as it requires sharding your growing relational database into clusters and orchestrating distributed queries between those shards. In this show, Marco and I discuss Citus’s approach to the distributed systems problems of a sharded relational database. This episode is a nice complement to previous episodes we have done with Ozgun and Craig from Citus, in which they gave a history of relational databases, and explained how Postgres compares to the wide variety of relational databases out there. Full disclosure: Citus Data is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Postgres Sharding and Scalability with Marco Slot", + "Episodes Uid": "SED3119700362", + "Episodes Audio File": "d12536dd4eac482508f2b14e4e4e8bd2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "33e", + "Episodes ID": "f624943a-e328-11ea-91a2-ef3821545a2c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/TinderManagement.mp3", + "Episodes Pubdate Date": "2017-10-09", + "Episodes Summary": "

Tinder is a rapidly growing social network for meeting people and dating. In the past few years, Tinder’s userbase has grown rapidly, and the engineering team has scaled to meet the demands of increased popularity.

On Tinder, you are presented with a queue of suggested people that you might match with, and you swipe left or right to indicate that you like or dislike them. Creating that queue of suggestions is a complex engineering problem. Many factors go into the suggestions that Tinder gives you: geotargeting, food preferences, your favorite band, your photos, and the people you have swiped on in the past.

Bryan Li is an engineering manager at Tinder, and he joins the show to describe the interaction between the mobile client, backend servers, and the offline analytics and machine learning. We also talk about managing different teams and how to reorganize smoothly as a company grows.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! The Software Engineering Daily open source community is building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend. If you are interested in contributing, check out github.com/softwareengineeringdaily–or send me an email: jeff@softwareengineeringdaily.com

", + "Episodes Title": "Tinder Engineering Management with Bryan Li", + "Episodes Uid": "SED2318066097", + "Episodes Audio File": "72692e99ba55bd9731ea16f57015a636.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4gm", + "Episodes ID": "f15bccde-e328-11ea-91a2-7b750319b2ff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_14_Druid.mp3", + "Episodes Pubdate Date": "2018-09-14", + "Episodes Summary": "

Modern applications produce large numbers of events. These events can be users clicking, IoT sensors accumulating data, or log messages.

The cost of cloud storage and compute continues to drop, so engineers can afford to build applications around these high volumes of events, and a variety of tools have been developed to process them. Apache Kafka is widely used to store and queue these streams of data, and Apache Spark and Apache Flink are stream processing systems that are used to perform general purpose computations across this event stream data.

Kafka, Spark, and Flink are great general purpose tools, but there is also room for a more narrow set of distributed systems tools to support high volume event data. Apache Druid is an open source database built for high performance, read only analytic workloads. Druid has a useful combination of features for event data workloads, including a column-oriented storage system, automatic search indexing, and a horizontally scalable architecture.

Druid’s feature set allows for new types of analytics applications to be built on top of it, including search applications, dashboards, and ad-hoc analytics. Fangjin Yang is a core contributor to Druid and the CEO of Imply.io, a company that makes a storage, querying, and visualization tool build on top of Druid. He joins the show to talk about the architecture of Druid and his company Imply.

", + "Episodes Title": "Druid Analytical Database with Fangjin Yang", + "Episodes Uid": "SED2338282378", + "Episodes Audio File": "4cecf60b3010f840509fd6a5309752ea.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jk", + "Episodes ID": "03dc32ea-e329-11ea-91a2-c30a1c8903ab", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/multiagent-systems_edited_1.mp3", + "Episodes Pubdate Date": "2017-03-21", + "Episodes Summary": "

Multiagent systems involve the interaction of autonomous agents that may be acting independently or in collaboration with each other. Examples of these systems include financial markets, robot soccer matches, and automated warehouses. Today’s guest Peter Stone is a professor of computer science who specializies in multiagent systems and robotics.

In this episode, we discuss some of the canonical problems of multiagent systems, which have some overlap with the canonical problems of distributed systems–for example, the problems of coordinating between different agents with varying levels of trust resembles the problem of establishing consistency across servers in a database cluster.

Peter has recently contributed to the 100 year study of artificial intelligence, so we also had a chance to discuss the opportunities and roadblocks for AI in the near future. And since Peter teaches computer science at my alma mater, UT Austin, I had to ask him a few questions about the curriculum.

", + "Episodes Title": "Multiagent Systems with Peter Stone", + "Episodes Uid": "SED6688142693", + "Episodes Audio File": "a26928d8d9ee11a76ed4566129e0422e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xe", + "Episodes ID": "ed4f8e6e-e328-11ea-91a2-43d2bd9a57ce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_11_JavaScriptCharlesMaxWood.mp3", + "Episodes Pubdate Date": "2019-07-11", + "Episodes Summary": "

Software engineers have a wide variety of media to choose from, including podcasts, blogs, YouTube videos, conferences. The amount of software engineering media that is available is growing and accelerating.

Eight years ago, there were not as many options for information about software. Charles Max Wood founded Devchat.tv to create a network of podcasts and other content for software engineers. Today, his podcasts include the popular shows JavaScript Jabber, Ruby Rogues, and Adventures in Angular.

Chuck joins the show for a conversation about software media. This was his second time on the show, with his first episode exploring his podcast JavaScript Jabber.

", + "Episodes Title": "Software Media with Charles Max Wood", + "Episodes Uid": "SED2106502362", + "Episodes Audio File": "70a31ee0b6ea6f515487be4eb018f1c8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2u4", + "Episodes ID": "f862d37e-e328-11ea-91a2-9ff6cff66499", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ServiceMesh.mp3", + "Episodes Pubdate Date": "2017-06-26", + "Episodes Summary": "

Containers make it easier for engineers to deploy software. Orchestration systems like Kubernetes make it easier to manage and scale the different containers that contain services. The popular container infrastructure powered by Kubernetes is often called “cloud native.”

On Software Engineering Daily, we have been exploring cloud native software to get a complete picture of the problems in the space, and the projects that are being worked on as solutions.

One area of interest: how should services communicate with each other? What should be standardized? How can you make it easy to identify problems and avoid cascading failures? One solution is the service mesh, a tool that allows services to communicate with each other more safely and effectively.

William Morgan was an engineer who helped scale Twitter in the early days when the company was dealing with lots of outages. He was on the show previously to discuss scaling Twitter, and in today’s episode we go into the company that he is running, Buoyant, where he works on building a service mesh called Linkerd.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Scaling Twitter

What’s a Service Mesh and Why Do I Need One?

Buoyant is hiring: email william@buoyant.io

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Service Mesh with William Morgan", + "Episodes Uid": "SED1271177650", + "Episodes Audio File": "108d8be859e743b56cb58ccaf2624f60.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2kl", + "Episodes ID": "0119f574-e329-11ea-91a2-0b4c601ea7eb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/FutureofReactnative.mp3", + "Episodes Pubdate Date": "2017-04-11", + "Episodes Summary": "

React Native has unlocked native mobile development to web engineers who may now apply their skills to build iOS and Android applications in JavaScript. For the first time, cross platform JavaScript-based applications feel as if they were written in the native language of choice for the platforms.

Businesses who choose to adopt React Native for their native app development also see great benefits such as the ability to push new JavaScript code without going through the app store review process, and the ability to share code and business behaviors across the iOS and Android platforms.

Expo is building a cross-platform native runtime for React Native. Expo brings the benefits of deployment and iterative development to native without sacrificing any user experience costs. Expo plans to do this with their native SDK, custom development environment, and tools built in collaboration with Facebook like create-react-native-app.

React Native has the incredible potential to revolutionize all user interface development with its core set of cross-platform UI primitives, and React’s popular declarative rendering pattern. So in this episode Brent Vatne and Adam Perry join Caleb Meredith to first discuss Expo and the future of React Native to try and answer the question: can React Native become the one UI framework to rule them all?

", + "Episodes Title": "The Future of React Native with Brent Vatne and Adam Perry", + "Episodes Uid": "SED1034937943", + "Episodes Audio File": "efc3c21c636222f8db1d00d42ea7d8f0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3wl", + "Episodes ID": "f2d24ef8-e328-11ea-91a2-df9e33732ffe", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_01_ScalingEthereum.mp3", + "Episodes Pubdate Date": "2018-06-01", + "Episodes Summary": "

Cryptocurrency infrastructure is a new form of software. Thousands of developers are submitting transactions to Bitcoin and Ethereum, and this transaction volume tests the scalability of current blockchain implementations. The bottlenecks in scalability lead to slow transaction times and high fees.

Over the last twenty years, engineers have learned how to scale databases. We’ve learned how to scale Internet applications like e-commerce stores and online games. It’s easy to forget, but there was a time when those systems didn’t perform well either.

Scaling a blockchain is different than scaling a relational database or a microservices infrastructure. Blockchains are peer-to-peer databases with an append only ledger shared by thousands of nodes. With different scalability solutions, there are tradeoffs between decentralization, scalability, and security. As an example, in Bitcoin, the core developers are working towards deployment and adoption of lightning network. Some would argue that this approach favors scalability over decentralization.

Today’s show is about scaling Ethereum. Raul Jordan and Preston Van Loon are developers who are part of Prysmatic Labs, a team building a sharding implementation for the Go Ethereum client. In this episode, we discuss Ethereum’s approaches to scaling, including sharding and Plasma.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Scaling Ethereum with Raul Jordan and Preston Van Loon", + "Episodes Uid": "SED3901105645", + "Episodes Audio File": "5d2942aec6bce7eb4210727f96bc128b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5s4", + "Episodes ID": "ede1e016-e328-11ea-91a2-f72ac9545a52", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_30_DigitalTransformationCapitalOne.mp3", + "Episodes Pubdate Date": "2019-05-30", + "Episodes Summary": "

Cloud computing, open source, and mobile computing are trends that affect every organization. When a large organization adapts to these trends, it is commonly referred to as a “digital transformation”.

Digital transformation causes many companies to reframe their business as a software company. A candy manufacturer now must think of itself as a software company that makes candy. An insurance company must now think of itself as a software company that issues insurance.

Capital One is a bank that was started in 1988. Capital One has always had an emphasis on software, but the company’s digital transformation has affected it as much any other company. The company is migrating to the cloud, building out microservices, rolling out continuous delivery pipelines, and shifting the internal culture to be more adept at using software.

Hillary McTigue is a senior director of data engineering at Capital One. She joins the show to discuss her experience implementing a digital transformation within a large company. Subjects we discuss include culture, management strategy, and the sequencing of different phases of a digital transformation.

Full disclosure: Capital One is a sponsor of Software Engineering Daily.

We are hiring two interns for software engineering and business development! If you are interested in either position, send an email with your resume to jeff@softwareengineeringdaily.com with “Internship” in the subject line.

", + "Episodes Title": "Digital Transformation: Capital One with Hillary McTigue", + "Episodes Uid": "SED3113564324", + "Episodes Audio File": "1ecafefe8a1a0a002ead7a80a5643c20.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ag", + "Episodes ID": "f55401a8-e328-11ea-91a2-7f1f07a46756", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/AWSLambda.mp3", + "Episodes Pubdate Date": "2017-12-07", + "Episodes Summary": "

Developers can build networked applications today without having to deploy their code to a server. These “serverless” applications are constructed from managed services and functions-as-a-service.

Managed services are cloud offerings like database-as-a-service, queueing-as-a-service, or search-as-a-service. These managed services are easy to use. They take care of operational burdens like scalability and outages. But managed services typically solve a narrow use case. You can’t build an application entirely out of managed services.

Managed services are scalable and narrow. Functions-as-a-service are scalable and flexible.

With managed services, you make remote calls to a service with a well-defined API. With functions-as-a-service, you can deploy your own code. But functions-as-a-service execute against transient, unreliable compute resources. They aren’t a good fit for low latency computation, and the code you run on them should be stateless.

Managed services and functions-as-a-service are the perfect complements.

Managed services provide you with well-defined server abstractions that every application needs—like databases, search indexes, and queues. Functions as a service offer flexible “glue code” that you can use to create custom interactions between the managed services.

The term “serverless” is used to describe the applications that are built entirely with managed services and functions as a service.

Serverless applications are dramatically simpler to build and easier to operate than cloud applications of the past. The costs of managed services can get expensive, but the costs of functions as a service can cost 1/10th of what it might take to run a server that is handling your requests.

Whether the size of your bill will increase or decrease as your company becomes “serverless” is less of an issue than the fact that your employees will be more productive: serverless applications have less operational burden, so developers spend more time architecting and implementing software.

It has been 5 years since the Netflix infrastructure team was talking about the aspirational goal of a “no-ops” software culture. Your software should be so well-defined that you do not need regular intervention of ops staff to reboot your servers and reconfigure your load balancers. Serverless is a newer way of moving operational expense into capital expense.

Today’s guest Randall Hunt is a senior technical evangelist with Amazon Web Services. He travels around the world meeting developers and speaking at conferences about AWS Lambda, the functions as a service platform from Amazon. Randall has given some excellent talks about how to architect and build serverless applications (which I will add to the show notes), and today we explore those application patterns further.

Serverless Services – Randall Hunt

Randall Hunt at AWS Summit Seoul

Serverless, What is it Good For? Randall Hunt

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless Applications with Randall Hunt", + "Episodes Uid": "SED2479706081", + "Episodes Audio File": "4e8f0ce0b156ed593a469567a31268bd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7k8", + "Episodes ID": "40e43b82-e6c2-11ea-b4fb-e70b02c36880", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_25_LawMarkRadcliffe.mp3", + "Episodes Pubdate Date": "2020-08-25", + "Episodes Summary": "

As software permeates our lives, there are an increased number of situations where the legal system must be designed to account for that software. Whether the issues are open source licensing, cryptocurrencies, or worker classifications, software overlaps heavily with the law.

Just as software is crafted by engineers, the legal structure around software is crafted by lawyers. There are large law firms that have built their business by knowing how to navigate these software and business questions.

Mark Radcliffe is a lawyer who has been working with software companies for decades. He joins the show to talk about the intersection of software and the law, which we discuss from multiple points of view.

", + "Episodes Title": "Software and the Law with Mark Radcliffe", + "Episodes Uid": "SED4794726189", + "Episodes Audio File": "a2f27d21f4b9a3a2384de78624c4ab42.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2fz", + "Episodes ID": "091fc06e-e329-11ea-91a2-9796098a18da", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/developeronfire_1.mp3", + "Episodes Pubdate Date": "2017-02-01", + "Episodes Summary": "

Software developers succeed by combining technical ability, communication skills, and well-reasoned philosophies to craft information systems. Where this podcast focuses on the information systems, Developer On Fire focuses on the engineers who built them.

Dave Rael started his podcast as a way to overcome fear and access an entrepreneurial side of himself. In his interviews with prominent engineers, Dave identifies patterns and strategies that have enabled his guests to succeed. He also finds the human side–namely the fallibilities and failures–of legendary developers, which makes it easier to imagine ourselves accomplishing the feats of his guests.

", + "Episodes Title": "Developer On Fire with Dave Rael", + "Episodes Uid": "SED3648137962", + "Episodes Audio File": "8962b05270649caefa4d8d581300cc5a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "33c", + "Episodes ID": "f62e3832-e328-11ea-91a2-6379b676cc20", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/AugustineFou.mp3", + "Episodes Pubdate Date": "2017-10-05", + "Episodes Summary": "

Advertising fraud continues to plague the Internet. We do not know the scope and scale of that fraud. How many ads on the Internet are viewed by bots? Estimations range from 2% to 99%.

Advertisers are slowly becoming more educated about fraud, thanks in part to Dr. Augustine Fou. Dr. Fou is a full-time advertising fraud researcher. He looks at data sets of billions of ad impressions to figure out how fraud works and help victims of ad fraud make their case.

Last year, Dr. Fou came on the show to give an overview of his perspective on the world of ad fraud. Today, we dive into the importance of Twitter in ad fraud schemes. We also talk about the severity of fraud on mobile apps. If you downloaded a flashlight app, or an alarm clock app, or a keyboard, that app could be displaying hidden ads that never actually show up.

Stay tuned at the end of the episode for Jeff Meyerson’s tip about getting into a new job: brought to you by Indeed Prime.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! The Software Engineering Daily open source community is building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend. If you are interested in contributing, check out github.com/softwareengineeringdaily–or send me an email: jeff@softwareengineeringdaily.com

", + "Episodes Title": "Ad Fraud Science with Augustine Fou", + "Episodes Uid": "SED4777674200", + "Episodes Audio File": "e84a2b74b6ca230edc6cafbb31b11c4f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5gt", + "Episodes ID": "eefb4938-e328-11ea-91a2-1f87644e655b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_15_Gitlab.mp3", + "Episodes Pubdate Date": "2019-03-15", + "Episodes Summary": "

GitLab is an open source platform for software development.

GitLab started with the ability to manage git repositories and now has functionality for collaboration, issue tracking, continuous integration, logging, and tracing. GitLab’s core business is selling to enterprises who want a self-hosted git installation, such as banks or other companies who prefer not to use a git service in the cloud.

The vision for GitLab is to provide a platform for managing the full software development lifecycle, from code hosting to deployment–as well as tools for observability and project management.

Sid Sijbrandij is the CEO of GitLab and he joins the show to talk about the product, the business, and the company’s vision for the future. GitLab’s strategy is to offer a set of tools that work for developers out of the box, cutting down on time spent integrating each individual vendor.

", + "Episodes Title": "GitLab with Sid Sijbrandij", + "Episodes Uid": "SED7254652934", + "Episodes Audio File": "62fa287055785d9208325d4b5e78b644.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4nq", + "Episodes ID": "f1192654-e328-11ea-91a2-af87f3cc34c2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_05_Scalyr_Engineering.mp3", + "Episodes Pubdate Date": "2018-10-05", + "Episodes Summary": "

Log messages are fast, high volume, unstructured data. Logs are often the source of metrics, alerts, and dashboards, so these critical systems are downstream from a log management system. A log management system needs to be highly available, so that a failure in one part of your system will not be correlated with failure of the log management system.

Users of a log management system are often building tools based off of the query engine of that log management system. For example, I might build a dashboard that gives me a line graph representing the number of times a certain log message is alerting me due to a memory warning. I write a query to return the instances of these memory warnings, and my line graph is a visual representation that query. A log management system needs to be able to quickly serve users that are querying their logs–whether for dashboards or for ad-hoc queries.

When logs are ingested by a log management system, the logs get parsed in a way that can bring some structure to the blob of text that is a raw log message. Some log management systems will then add the log message to an index. An index can allow for very fast lookups of particular types of queries. But an index also has certain constraints–such as processing regular expression queries.

Steve Newman is the CEO and founder of Scalyr, a log management system that uses a column-oriented data storage system instead of the more conventional index-based log management systems. Today’s episode is a great case study in distributed systems tradeoffs. Steve talks in great detail about how Scalyr maintains high uptime, and its system for ingesting logs and serving queries.

", + "Episodes Title": "Scalyr: Column-Oriented Log Management with Steve Newman", + "Episodes Uid": "SED5438752610", + "Episodes Audio File": "1d67486b6bdc35e2df1a9dff5e86176b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "49b", + "Episodes ID": "f20ad094-e328-11ea-91a2-4b4b281d94f6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_30_EdgeKubernetes.mp3", + "Episodes Pubdate Date": "2018-07-30", + "Episodes Summary": "

“Edge computing” is a term used to define computation that takes place in an environment outside of a data center. Edge computing is a broad term. Your smartphone is an edge device. A self-driving car is an edge device. A security camera with a computer chip is an edge device.

These “edge devices” have existed for a long time now, but the term “edge computing” has only started being used more recently. Why is that? It is mostly because the volume of data produced by edge devices, and the type of computation that we want from edge devices is changing.

We want to develop large sensor networks to enable smart factories, and smart agriculture fields. We want our smartphones to have machine learning models that get updated as frequently as possible. We want to use self-driving cars, and drones, and smart refrigerators to develop elaborate mesh networks–and perhaps even have micropayments between machines, so that computation can be offloaded from edge devices to a nearby mesh network for a small price.

Kubernetes is a tool for orchestrating distributed, containerized computation. Just as Kubernetes is being widely used for data center infrastructure, it can also be used to orchestrate computation among nodes on-premise at a factory, or in a smart agriculture environment. In today’s episode, Venkat Yalla from Microsoft joins the show to talk about Kubernetes at the edge, and how Internet of things applications can use Kubernetes for their deployments today–and what the future might hold. Full disclosure: Microsoft is a sponsor of SE Daily.

", + "Episodes Title": "Edge Kubernetes with Venkat Yalla", + "Episodes Uid": "SED9191463408", + "Episodes Audio File": "10678171bb84ac67bb3a09fafa623fc9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3k9", + "Episodes ID": "f40597a8-e328-11ea-91a2-1f4d9263fa04", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_08_Aragon.mp3", + "Episodes Pubdate Date": "2018-03-08", + "Episodes Summary": "

Humans organize into groups. There are lots of group types: religions, corporations, national governments, state governments, citizenries, clubs, musical bands.

Every group has governance. Governance defines the rules, and the ways that rules change. The United States requires citizens to pay taxes. A corporation requires you to show up to work, but they have to pay you a salary.

Most groups today are managed by people. If you break a law, you have to go to court and sit in front of a judge and jury, who decide how you will be punished. If you work at a corporation, and you have a problem with your manager, you go to HR to arbitrate it.

These organizations are centralized. There is a governing body who sets the rules. If there is an ambiguity, the person who happens to be in power gets to decide how the ambiguity is resolved. Power is centralized in that governing body.

These organizations are run by people. The governance of these organizations is enforced only to the extent that the human government carries out its duties.

A decentralized autonomous organization is a group that can run with neither centralized nor human intervention. It is decentralized and autonomous. It is a DAO.

Aragon is a platform for running and managing decentralized autonomous organizations. Luis Cuende is the founder of Aragon, and joins the show to explain what a DAO is and why people want to create them. We also talk about the engineering of Aragon and the structure of its ICO—which raised $25m via token sale.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "How Aragon Manages DAOs with Luis Cuende", + "Episodes Uid": "SED3797016874", + "Episodes Audio File": "fe7ef8ee8518398fefc86cff12078bab.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "54a", + "Episodes ID": "f01ee996-e328-11ea-91a2-7f8b77ea2ba3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_18_MarketStrategy.mp3", + "Episodes Pubdate Date": "2018-12-18", + "Episodes Summary": "

Market strategy defines how a company is positioning itself to be successful. This strategy encompasses engineering, sales, marketing, recruiting, and everything else within a company.

Herb Cunitz has led teams at Hortonworks, VMware, SpringSource, and several other companies over his 30 year career in software. After working as president of Hortonworks, Herb started AccelG2M. AccelG2M works with software companies to define their go-to-market strategy.

Software companies require a great deal of long-term strategic thinking. Engineering, sales, marketing, and leadership must work together to build a plan that will allow the company to reach an exit: either an acquisition or an IPO.

Executives at a software company must create a clear strategy and communicate it to the employees throughout the organization. The strategy must be implemented, meeting deadlines and hitting milestones. New team members must be recruited, and unsuccessful workers must be let go.

In today’s show, Herb provides some invaluable strategic wisdom for anyone working in software–whether you are an engineer, salesperson, or investor.

", + "Episodes Title": "Market Strategy with Herb Cunitz", + "Episodes Uid": "SED9688662038", + "Episodes Audio File": "f8ead7d65d89f88b0789b9ac31d2c34e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3so", + "Episodes ID": "f2ec2422-e328-11ea-91a2-9bb640f62449", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_24_PrestoandParquet.mp3", + "Episodes Pubdate Date": "2018-05-24", + "Episodes Summary": "

When a user takes a ride on Uber, the app on the user’s phone is communicating with Uber’s backend infrastructure, which is writing to a database that maintains the state of that user’s activity. This database is known as a transactional database or “OLTP” (online transaction processing). Every active user and driver and UberEATS restaurant is writing data to the transactional data store.

Periodically, that data is copied from the transactional data system to a different data storage system, where that data can be queried for large-scale data analysis. For example, if a data scientist at Uber wants to get the average amount of miles that a given user rode in February, that data scientist would issue a query to the analytical data cluster.

Uber uses the Hadoop distributed file system (HDFS) to store analytical data. On this file system, Uber has a version history of all of the company’s useful historical data. Trip history, rider activity, driver activity–every data point that is in the transactional database–but in a file format that is easier to query for large scale processing. This file format is known as Parquet.

Data scientists, machine learning engineers, and real-time application developers all depend on the massive quantities of data that are stored in these Parquet files on Uber’s HDFS cluster. To simplify the access of that data by many different clients, Uber uses Presto, an analytical query engine originally built at Facebook.

Presto translates SQL queries into whatever query language is necessary to access the underlying storage medium–whether that storage system is an ElasticSearch cluster, a set of Parquet files, or a relational database. Presto is useful because it simplifies the relationship between data engineers and the application developers who are building on top of the data engineering infrastructure.

In today’s show, Zhenxiao Luo joins to give an end-to-end description of Uber’s data infrastructure–from the ingest point of the OLTP database to the OLAP data storage system on HDFS, to the wide range of data systems and applications that run on top of that OLAP data.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Uber’s Data Platform with Zhenxiao Luo", + "Episodes Uid": "SED6224119286", + "Episodes Audio File": "dff1f352ae790c01fe14caee18234c9b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "63f", + "Episodes ID": "eca27fee-e328-11ea-91a2-67112ad375b3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_26_FacebookScalingPedram.mp3", + "Episodes Pubdate Date": "2019-08-26", + "Episodes Summary": "

Facebook is a large multiuser application. Scaling Facebook was different than scaling a single-user application such as an ecommerce store or a search engine. A social network is faced with unique infrastructure scalability challenges, as well as subjective questions around user communications, privacy, and content.

Pedram Keyani worked at Google before joining Facebook in 2007. In his years at Facebook, he worked on infrastructure, internal tools, and management. He became deeply familiar with the company culture and its operations. Pedram joins the show to talk about how Facebook has scaled and the lessons he took away from his time there.

After his time at Facebook, Pedram joined Uber, where he worked as a director of engineering for four years. Uber is another multi-user application, with a very different set of constraints. At Uber, Pedram worked on several projects, including Uber’s push into China, which he describes as an intense, competitive experience. Pedram is able to contrast the culture and scaling processes of Uber, Facebook, and Google which made this a rare opportunity to see how three different high performing companies build software differently.

", + "Episodes Title": "Facebook Scaling with Pedram Keyani", + "Episodes Uid": "SED5158250982", + "Episodes Audio File": "d2bb16ad1b0471d6332043b55fbfabf3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "58n", + "Episodes ID": "efc1a240-e328-11ea-91a2-77f7a12a59de", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_17_Looker.mp3", + "Episodes Pubdate Date": "2019-01-17", + "Episodes Summary": "

If a business has been operating successfully for a few years, that business has accumulated a high volume of data. That data exists in spreadsheets, CSV files, log files, and balance sheets. Data might be spread across local files on a user’s laptop, databases in the cloud, or storage systems in an on-premise data center.

Older businesses have more data, in more places, in more formats. Legacy systems and old batch processing jobs that have been running for years are taking data from one place and porting it to another.

Every mature company needs to access and analyze the data in all of these different places–whether they are a publication with millions of readers like The Economist or a fast growing infrastructure provider like Twilio.

“Business intelligence” is a term often used to describe tools for analyzing data in the form of charts, graphs, and reports. Business intelligence applications are crucial to the success of a business because they are used by everyone in an organization–whether you are a business analyst forecasting sales for the next quarter, an engineer who is determining how many servers to provision, or a CEO trying to decide what the best area of your business to focus on is.

There have been several generations of business intelligence tools. Each generation of business intelligence is built for the trends and infrastructure of that generation.

Looker is a more recent business intelligence tool that was built in light of several trends in software: the growth in volume of data; the growth in the number of systems that users need; the changing types of users that need to access data; and the need to share business intelligence across social workplace tools like Slack, Asana, and email.

Daniel Mintz joins the show to describe his experience using business intelligence tooling and his work at Looker, as well as the landscape of business intelligence, ETL, and data engineering.

", + "Episodes Title": "Looker: Business Intelligence Platform with Daniel Mintz", + "Episodes Uid": "SED4328069285", + "Episodes Audio File": "0e3d0156702594f2a5804437d7d1042c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48o", + "Episodes ID": "f2196cb2-e328-11ea-91a2-bf262d938dfd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_25_StartEngine.mp3", + "Episodes Pubdate Date": "2018-07-25", + "Episodes Summary": "

Howard Marks ran two video game companies in the 90’s: Activision and Acclaim. While running these companies, he developed a love for entrepreneurship that he maintains today. Howard is the CEO of StartEngine, a company that functions as an accelerator, a crowdfunding platform, and ICO launcher.

Howard joins the show to talk about his background as an entrepreneur, as well as some modern alternative funding mechanisms that he’s working on at StartEngine. Hearing Howard’s thoughts on building a video game company in the 90’s was particularly new information to me–it’s an era of software development that we have not covered much at all.

As a side note–some listeners have asked recently why we cover subjects such as ICOs, when there have been so many dubious companies that have launched ICOs.

There are two reasons why we cover this area. Firstly, cryptocurrencies are a breakthrough computer science construct. It’s important for us to try to understand their implications. The other reason why we cover ICOs is that some technology companies require high upfront capital costs. The amount of capital you have available affects the speed at which your engineering team can move. New funding mechanisms could mean more capital for certain types of software companies–and this could be a good thing and a bad thing, depending on the company.

", + "Episodes Title": "Video Games and Funding Techniques with Howard Marks", + "Episodes Uid": "SED7858475422", + "Episodes Audio File": "f01e84746280e519faad6e7614bdcadd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "63b", + "Episodes ID": "ecb4dc16-e328-11ea-91a2-6f7a29edf734", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_20_MachineLearningforInsurancewithGordonWintrob.mp3", + "Episodes Pubdate Date": "2019-08-20", + "Episodes Summary": "

Insurance is an old business. Individuals and businesses have been buying insurance policies for decades. These insurance policies can cost hundreds, thousands, or tens of thousands of dollars per year.  

Software is remaking the insurance industry.

One way new software can improve the insurance industry is through better brokerage technology. Insurance involves carriers and brokers, who work together on delivering insurance solutions to customers. The initiation and closing of an insurance transaction often involves lots of emails, PDF files, and antiquated software systems. Technology improvements will smooth out this process and reduce manual overhead.

Another way insurance can improve thanks to technology is through smarter pricing. The price of an insurance policy is offered to a customer based on how risky the insurance policy is, how large the customer pool is, and how much the insurance company could lose in the event that it would have to pay out an insurance policy. These risk profiles are calculated based on historical data.

Gordon Wintrob is the co-founder and CTO of Newfront Insurance. Gordon joins the show to discuss the insurance industry and how his company got started.

", + "Episodes Title": "Insurance Software with Gordon Wintrob", + "Episodes Uid": "SED3565487105", + "Episodes Audio File": "a2a9462feef371207e6e6802614f7f2c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "44v", + "Episodes ID": "f266d95c-e328-11ea-91a2-6f4c7f877648", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_02_Kademlia.mp3", + "Episodes Pubdate Date": "2018-07-02", + "Episodes Summary": "

Napster, Kazaa, and Bittorrent are peer-to-peer file sharing systems. In these P2P systems, nodes need to find each other. Users need to be able to search for files that exist across the system. P2P systems are decentralized, so these routing problems must be solved without a centralized service in the middle.

Without a centralized service that has all the information in one place, how can you solve these problems of node discovery and file lookup? This is the central question that Petar Maymounkov sought to answer with Kademlia.

Kademlia is a peer-to-peer distributed hash table. Kademlia implements the “put” and “get” operations of an efficiently scalable hash table without using any centralized service. Each node in the system maintains its own routing table. When a user queries the system (a “get” operation), that query is serviced by the nodes coordinating with each other to intelligently route the user to their target location. When a file is stored (a “put” operation), that update to the file system can propagate through the network in a decentralized, uncoordinated way.

Petar joins the show to give a brief history of P2P networks, why he created Kademlia, and what he is working on today.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kademlia: P2P Distributed Hash Table with Petar Maymounkov", + "Episodes Uid": "SED2916880574", + "Episodes Audio File": "184c0c3350eb59669df2d67713219e29.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4vv", + "Episodes ID": "f0a50a3a-e328-11ea-91a2-5bad18269f8b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_07_DavePatterson.mp3", + "Episodes Pubdate Date": "2018-11-07", + "Episodes Summary": "

An instruction set defines a low level programming language for moving information throughout a computer. In the early 1970’s, the prevalent instruction set language used a large vocabulary of different instructions. One justification for a large instruction set was that it would give a programmer more freedom to express the logic of their programs.

Many of these instructions were rarely used. Think of your favorite programming language (or your favorite human language). What percentage of words in the vocabulary do you need to communicate effectively? We sometimes call these language features “syntactic sugar”. They add expressivity to a language, but may not improve functionality or efficiency.

These extra language features can have a cost.

Dave Patterson and John Hennessy created the RISC architecture: Reduced Instruction Set Compiler architecture. RISC proposed reducing the size of the instruction set so that the important instructions could be optimized for. Programs would become more efficient, easier to analyze, and easier to debug.

Dave Patterson’s first paper on RISC was rejected. He continued to research the architecture and advocate for it. Eventually RISC became widely accepted, and Dave won a Turing Award together with John Hennessy.

Dave joins the show to talk about his work on RISC and his continued work in computer science research to the present. He is involved in the Berkeley RISELab and works at Google on the Tensor Processing Unit.

Machine learning is an ocean of new scientific breakthroughs and applications that will change our lives. It was inspiring to hear Dave talk about the changing nature of computing, from cloud computing to security to hardware design.

", + "Episodes Title": "Computer Architecture with Dave Patterson", + "Episodes Uid": "SED5633133839", + "Episodes Audio File": "4bdae7d858b55c36e491541be1ec6e25.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ly", + "Episodes ID": "ee774296-e328-11ea-91a2-f7ae65039e6c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_18_FacebookOpenSource.mp3", + "Episodes Pubdate Date": "2019-04-18", + "Episodes Summary": "

RECENT UPDATES:

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

FindCollabs Hackathon has ended–winners will probably be announced by the time this episode airs; we will be announcing our next hackathon in a few weeks, so stay tuned

Open source policy has become a business issue as well as a political one.

Businesses like Elastic, MongoDB (the company), and Redis Labs have started to view the open source licenses of the projects they work on as a means for business defensibility against cloud providers offering similar services. It remains to be seen how viable this strategy will be for the commercial open source vendors.

Companies that do not directly sell commercial open source are also grappling with questions around open source licensing. Facebook has become a force in the open source world through projects like React and GraphQL. Facebook leads these projects, but Facebook is not monetizing them other than to the extent that they use the projects to build Facebook.com.

Facebook’s incentives are aligned with the rest of the industry on the quality of the GraphQL and React projects. Proper licensing can help Facebook keep those incentives in alignment.

Joel Marcey, Michael Cheng, and Kathy Kam from Facebook join me for a discussion of the state of open source licensing, and how that impacts Facebook.

", + "Episodes Title": "Facebook OSS License Policy with Joel Marcey, Michael Cheng, and Kathy Kam", + "Episodes Uid": "SED8020671906", + "Episodes Audio File": "ef88f0a1bd0a661ffc3e1d97c99e3969.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5lx", + "Episodes ID": "ee80ce88-e328-11ea-91a2-8b6ac6ca5e17", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_16_LyftDataDiscovery.mp3", + "Episodes Pubdate Date": "2019-04-16", + "Episodes Summary": "

RECENT UPDATES:

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

FindCollabs Hackathon has ended–winners will probably be announced by the time this episode airs; we will be announcing our next hackathon in a few weeks, so stay tuned

Lyft is a ridesharing company with petabytes of data. Within Lyft, many different employees can use those data sets to build useful applications.

A business analyst creates a dashboard to see how driver satisfaction is changing over time. An economist studies the pricing data to ensure that Lyft’s prices are competitive. A data scientist creates a report of how the speed of a ride correlates with 5 star ratings. A machine learning engineer trains a model to detect fraud on the platform.

All of these use cases make sense–and in each of them, the employee at Lyft needs to find the necessary data sets within the company to build their application. Amundsen is a tool for finding and discovering data sets within the company.

Tao Feng and Mark Grover are engineers at Lyft and join the show to talk about the problem of data discovery and the tools they have built at Lyft.

", + "Episodes Title": "Lyft Data Discovery with Tao Feng and Mark Grover", + "Episodes Uid": "SED2651753261", + "Episodes Audio File": "3e800a264e4acc385223c83edd47c98a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ia", + "Episodes ID": "05b83ff0-e329-11ea-91a2-83c0af953006", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/OperationswithCharityMajors.mp3", + "Episodes Pubdate Date": "2017-03-01", + "Episodes Summary": "

Parse was a backend as a service company built in 2011 before being acquired by Facebook in 2013. Building a backend as a service for developers requires walking a thin line between giving engineers lots of control and preventing those engineers from shooting themselves in the foot.

While she was at Parse, Charity Majors learned about the operational burdens of managing a service with high uptime requirements and deeply technical edge cases that could take down a user’s entire system. Charity took the lessons in systems engineering that she learned at Parse and cofounded Honeycomb.io, a service for observability and monitoring. Honeycomb is described as a tool for your systems like an IDE is to your code.

Parse was eventually shut down because the service did not have a place in the strategic plans of Facebook. Charity and I also discussed the lessons learned from how the Parse acquisition panned out–a useful conversation for anyone who is considering selling a company or acquiring a startup.

", + "Episodes Title": "Parse and Operations with Charity Majors", + "Episodes Uid": "SED2426224500", + "Episodes Audio File": "77fc68fb9bb6498935972d0bf53ff355.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4kl", + "Episodes ID": "f137cd16-e328-11ea-91a2-eb42742db6b7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_26_Modern_JavaScript.mp3", + "Episodes Pubdate Date": "2018-09-26", + "Episodes Summary": "

JavaScript performance has improved over time due to advances in JavaScript engines such as Google’s V8. A JavaScript engine performs compiler optimization, garbage collection, hot code management, caching, and other runtime aspects that keep a JavaScript program running efficiently.  JavaScript runs in browsers and servers. The resources that are available to a JavaScript engine vary widely across different machines.

JavaScript code is parsed into an abstract tree before being handed off to the compiler toolchain, in which one or more optimizing compilers produce efficient low-level code. In recent shows about WebAssembly, we have covered compiler pipelines. In an episode about GraalVM, we explored the impact that “code shape” has on the efficiency of JavaScript execution.

Mathias Bynens is a developer advocate at Google working on the V8 JavaScript engine team. In today’s show we explore how a JavaScript engine works, and how compiler toolchains can adapt the hot code paths depending on what code needs to be optimized for.

", + "Episodes Title": "JavaScript Engines with Mathias Bynens", + "Episodes Uid": "SED8027053508", + "Episodes Audio File": "03288526a9475e265b306fcbf294a4bd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2fd", + "Episodes ID": "0a1c5112-e329-11ea-91a2-1bf72310c5d9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/developing_reactive_microservices_edited.mp3", + "Episodes Pubdate Date": "2017-01-24", + "Episodes Summary": "

The goals of microservices are the same as what we have pursued in software engineering for decades: isolation, decoupling, maintainability, scalability. The reason that we use the term microservices is not because we have a completely different idea of what a service is than we used to. We use the term microservices because we are signaling that we need to achieve these architectural goals in a different way than we needed to 10-15 years ago.

Markus Eisele is a developer advocate at Lightbend. He joins the show to discuss how enterprises are moving from monolithic architectures to microservices architectures, which has been touched on in previous shows. Lightbend makes a framework called Lagom, that suggests a opinionated strategy for moving towards microservices using message passing, CQRS, and other patterns that we explore.

Reactive Microservices Architecture 

", + "Episodes Title": "Reactive Microservices Development with Markus Eisele", + "Episodes Uid": "SED1281948517", + "Episodes Audio File": "83c0a4db59b6bba92f645d340dca7120.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2qj", + "Episodes ID": "fa95ca84-e328-11ea-91a2-b7aacd68fefd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Scuttlebutt.mp3", + "Episodes Pubdate Date": "2017-05-26", + "Episodes Summary": "

Social networks like Facebook and Twitter facilitate interactions between individuals. Every message I send to you on Facebook goes through Facebook’s servers before reaching you. This is known as the client-server model. Since the early days of the internet, engineers have always envisioned a peer-to-peer model, where I could communicate to you directly, without a company brokering that relationship.

Andre Staltz works on Scuttlebutt, a peer-to-peer system for social graphs, identity, and messaging. Scuttlebutt is used by a group of open-source hackers, many of whom live off-grid and do not have constant access to the Internet.

In this episode, we discuss why someone would want a peer-to-peer social network, how to build one, and the progress that has been made on Scuttlebutt by some of the most talented open-source engineers in the world.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Off-Grid Social Network with Andre Staltz", + "Episodes Uid": "SED8914795031", + "Episodes Audio File": "67ea0fa29629fcfd95f910a50cff3c75.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2mt", + "Episodes ID": "fdb5b0da-e328-11ea-91a2-03985becef5d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/GoogleBrain.mp3", + "Episodes Pubdate Date": "2017-05-01", + "Episodes Summary": "

Most popular music today uses a computer as the central instrument. A single musician is often selecting the instruments, programming the drum loops, composing the melodies, and mixing the track to get the right overall atmosphere.

With so much work to do on each song, popular musicians need to simplify–the result is that pop music today consists of simple melodies without much chord progression.

Magenta is a project out of Google Brain to design algorithms that learn how to generate art and music. One goal of Magenta is to advance the state of the art in machine intelligence for music and art generation. Another goal is to build a community of artists, coders, and machine learning researchers who can collaborate.

Engineers today are happy to outsource server management to a cloud service provider. Similarly, a musician can use Magenta for creation of a melody, so she can focus on other aspects of a song, such as instrumentation.

Doug Eck is a research scientist at Google. In today’s episode, we explore the Magenta project and the future of music.

Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup. We would love to get your feedback on Software Engineering Daily. Please fill out the listener survey, available on softwareengineeringdaily.com/survey.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to download this show’s transcript.

", + "Episodes Title": "Google Brain Music Generation with Doug Eck", + "Episodes Uid": "SED6418567027", + "Episodes Audio File": "322c65df7a6415b944252eb5dbda1bc2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3jl", + "Episodes ID": "f427d50c-e328-11ea-91a2-8bbab8a351a6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_27_ScaleSelfDriving.mp3", + "Episodes Pubdate Date": "2018-02-27", + "Episodes Summary": "

The easiest way to train a computer to recognize a picture of cat is to show the computer a million labeled images of cats. The easiest way to train a computer to recognize a stop sign is to show the computer a million labeled stop signs.

Supervised machine learning systems require labeled data. Today, most of that labeling needs to be done by humans. When a large tech company decides to “build a machine learning model,” that often requires a massive amount of effort to get labeled data.

Hundreds of thousands of knowledge workers around the world earn their income from labeling tasks. An example task might be “label all of the pedestrians in this intersection.” You receive a picture of a crowded intersection, and your task is to circle all the pedestrians. You have now created a piece of labeled data.

Scale API is a company that turns API requests into human tasks. Their most recent release is an API for labeling data that has been generated from sensors. As self-driving cars emerge onto our streets, the sensors on these cars generate LIDAR, radar, and camera data. The cars will interpret that data in real time using their machine learning models, and then they will send that data to the cloud so that the data can be processed offline to improve the machine learning models of every car on the road.

The first step in that processing pipeline is the labeling–which is the focus of today’s conversation. Alexandr Wang is the CEO of Scale, and he joins the show to discuss self-driving cars, labeling, and the company he co-founded.

A few notes before we get started. We just launched the Software Daily job board. To check it out, go to softwaredaily.com/jobs. You can post jobs, you can apply for jobs, and it’s all free. If you are looking to hire, or looking for a job, I recommend checking it out. And if you are looking for an internship, you can use the job board to apply for an internship at Software Engineering Daily.

Also, Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Scale Self-Driving with Alexandr Wang", + "Episodes Uid": "SED4345563504", + "Episodes Audio File": "7bbae7d4bb120d6a66a36518b566f56b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 400000000, + "Episodes ID": "f17adff2-e328-11ea-91a2-53a48a2532ea", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_05_Robinhood.mp3", + "Episodes Pubdate Date": "2018-09-05", + "Episodes Summary": "

Robinhood is a platform for buying and selling stocks, cryptocurrencies, and other assets. Since its founding in 2013, Robinhood has grown to have more than 3 million user accounts, which is approximately the same as the popular online broker E-Trade. With the surge in user growth and transaction volume, the demands on the software infrastructure have increased significantly.

When a user buys a stock on Robinhood, that transaction gets written to Kafka and Postgres. Multiple services get notified of the new entry on the Kafka topic, and those services process that new event using Kafka Streams. Kafka Streams are a way of reading streams of data out of Kafka with exactly-once semantics. Developers at Robinhood use a variety of languages to build services on top of these Kafka streams–including Python.

Commonly used systems for building stream processing tasks on top of a Kafka topic include Apache Flink and Apache Spark. Spark and Flink let you work with large data sets while maintaining high speed and fault-tolerance. These tools are written in Java. If you want to write a Python program that interfaces with Apache Spark, you have to pay an expensive serialization/deserialization cost as you move that object between Python and Spark.

Ask Solem is an engineer with Robinhood, and the author of Faust, a stream processing library that ports the ideas of Kafka Streams to Python. Faust provides stream processing and event processing in a manner that is similar to Kafka Streams, Apache Spark, and Apache Flink. He is also the author of the popular Celery asynchronous task queue. Ask joins the show to provide his perspective on large scale, distributed stream processing, and why he created Faust.

", + "Episodes Title": "Faust: Streaming at Robinhood with Ask Solem", + "Episodes Uid": "SED8515307237", + "Episodes Audio File": "577ca9daab3a6908e333ce9212ad6c75.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2u1", + "Episodes ID": "f81d4598-e328-11ea-91a2-2fe34f0b605e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/LinuxKernel.mp3", + "Episodes Pubdate Date": "2017-06-28", + "Episodes Summary": "

The code in the Linux kernel changes all the time–11k lines are added, 5.8k lines are removed, and 2k lines are modified DAILY. Linux is an open source operating system that has been worked on for 25 years, and one reason the project is able to move so fast is its governance and release structure.

Greg Kroah-Hartman is a fellow at the Linux Foundation, where he takes part in many of the developments in the kernel. This episode was a dive into how open source software gets built at scale and what is in store for the future. The Kubernetes project has drawn comparable attention to the size of Linux, and the Kubernetes project is learning how to manage open source from the Linux community.

Check out our new topic feeds, in iTunes or wherever you find your podcasts. We’ve sorted all 500 of our old episodes into categories like business, blockchain, cloud engineering, JavaScript, machine learning, and greatest hits. Whatever specific area of software you are curious about, we have a feed for you. Check the show notes for more details.

Kernel Development

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Linux Kernel Governance with Greg Kroah-Hartman", + "Episodes Uid": "SED2286708999", + "Episodes Audio File": "009cd93e89a5675b0a11c00ba18757c8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5tx", + "Episodes ID": "edb4f966-e328-11ea-91a2-db85fbe03279", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_12_HitenShah.mp3", + "Episodes Pubdate Date": "2019-06-12", + "Episodes Summary": "

The software market changes every year.

As individuals and enterprises become more willing to buy software, there are new markets for entrepreneurs to sell software to. Good software has high margins and high retention, so even a niche software business can prove profitable.

As software spreads across the world, developing countries are showing a willingness to buy the same software tools as the developed countries, making the niche software businesses even more successful than expected.

It’s a great time to start a software business. But the fundamental challenges faced by an entrepreneur have not gone away. An entrepreneur must find the necessary capital, build an initial product, iterate on that product, market to their audience, sell to their customers, and retain their users.

Hiten Shah is an entrepreneur and investor who has started several businesses, both successful and unsuccessful. He is also the host of the Startup Chat podcast, a show about strategies and tactics for software businesses. Hiten joins the show to discuss his experience in the software industry, including lessons on financing, product development, and the future of software products.

", + "Episodes Title": "Software Businesses with Hiten Shah", + "Episodes Uid": "SED2867070358", + "Episodes Audio File": "89f910de9537291aa21894b25443e528.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4zk", + "Episodes ID": "f0650584-e328-11ea-91a2-7745eb9e9ade", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_27_PersonalFinanceSoftware.mp3", + "Episodes Pubdate Date": "2018-11-27", + "Episodes Summary": "

Many people have saved some money which they want to invest for the future. Some people are happy investing their money in a roboadviser, which programmatically puts money into long-term investments. Other people want a more personal approach involving a certified financial planner (CFP). A CFP is a human who allocates capital for an individual based off of that individual’s preferences.

A CFP spends time and effort researching the options for a client. If the client only has a small amount of money (say, $15,000), it is not worth it for the CFP to spend much time on that account. As a result, there is a type of client who has saved a little bit of money, but has not saved enough to be an important client for a CFP.

Facet Wealth is a software company that makes software for CFPs to work more effectively with their client accounts. Facet Wealth has in-house CFPs who work with this software to manage client accounts. In addition, Facet Wealth buys client accounts from independent CFPs who have small accounts which they do not have time to manage. This is an innovative way to aggregate users onto the platform.

Gorkem Sevinc is CTO at Facet Wealth. He joins the show to describe the business and the software architecture of the company. We touched on many different areas–from human-computer interaction to the future of investing.

We recently launched a new podcast: Fintech Daily! Fintech Daily is about payments, cryptocurrencies, trading, and the intersection between finance and technology. You can find it on fintechdaily.co or Apple and Google podcasts. We are looking for other hosts who want to participate. If you are interested in becoming a host, send us an email: host@fintechdaily.co

", + "Episodes Title": "Facet Wealth Engineering with Gorkem Sevinc", + "Episodes Uid": "SED9997036572", + "Episodes Audio File": "e804293b5b22b6ead0c5bfbb6f3ba8bb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "66f", + "Episodes ID": "ec71c14c-e328-11ea-91a2-7f8c9f3194b5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_11_MongoData.mp3", + "Episodes Pubdate Date": "2019-09-11", + "Episodes Summary": "

A new software application has simple requirements for a database. 

The database needs to be written to and read from. The database fulfills simple needs such as storing user information and providing the application frontend with the necessary data to render a simple webpage of financial transactions or blog posts.

As an application becomes successful, the database grows in size. The complexity of queries increases, requiring more sophisticated logic in order to maintain performance. New databases need to be added to the overall system, as users begin to have demands for advanced features such as search, or analytics.

Over time, the requirements for a database expand into a need for a data platform. A data platform might include multiple databases such as a NoSQL database, a relational database, a data warehouse, and a search index. The relationships between these different databases can vary in terms of consistency requirements, latency, and scalability.

Andrew Davidson is the Director of Cloud Products at MongoDB. In a previous episode, Andrew discussed the tradeoffs of scaling databases while maintaining high performance indexing. Andrew returns to the show to discuss the emerging subject of “data platform.” 

As a growing number of companies have data requirements beyond that of a simple transactional database, Andrew’s work has increasingly involved figuring out the best ways for developers to adapt those transactional systems to providing a wider set of functionality. Full disclosure: MongoDB is a sponsor of Software Engineering Daily.

", + "Episodes Title": "MongoDB Data Platform with Andrew Davidson", + "Episodes Uid": "SED3392232095", + "Episodes Audio File": "085e01e9738b76aa9121eed87df16e7b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2qe", + "Episodes ID": "fb20f6e0-e328-11ea-91a2-779bf6734f99", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CNCF.mp3", + "Episodes Pubdate Date": "2017-05-19", + "Episodes Summary": "

Cloud computing changed how we develop applications for the web. Over the last decade, engineers have been learning how to build software in this new paradigm. The costs have gone down, but our nodes can fail at any time. We no longer have to manage individual servers, but the layers of virtualization and containerization require new strategies for communicating between services.

As we have adjusted to this new way of building applications, the term “cloud-native” has become a useful descriptor. Cloud native applications are modern distributed systems capable of scaling to tens of thousands of self healing multi-tenant nodes.

Open source projects such as Kubernetes, Prometheus, and Linkerd draw on the lessons of big technology companies like Google, Twitter, and SoundCloud. Engineers today don’t need to reinvent the key infrastructure of those companies. We can combine the open source cloud-native technologies and use them to build powerful systems.

Dan Kohn is the executive director of the Cloud Native Computing Foundation, and he joins me for an interview about the projects within the CNCF, how they fit together, and the future of computing.

Stay tuned at the end of the episode for Jeff Meyerson’s tip about job searching brought to you by Indeed Prime.

Measuring the Popularity of Kubernetes Using BigQuery

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Cloud Native Projects with Dan Kohn", + "Episodes Uid": "SED3336585842", + "Episodes Audio File": "406a0a6bfc642902f538a8394c269dfa.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48z", + "Episodes ID": "f1dd02f4-e328-11ea-91a2-833650e85011", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_03_GraalVM.mp3", + "Episodes Pubdate Date": "2018-08-03", + "Episodes Summary": "

Java programs compile into Java bytecode. Java bytecode executes in the Java Virtual Machine, a runtime environment that compiles that bytecode further into machine code, and optimizes the runtime by identifying “hot” code paths and keeping those hot code paths executing quickly.

The Java Virtual Machine is a popular platform for building languages on top of. Languages like Scala and Clojure compile down to Java bytecode, and can take advantage of the garbage collection system and the code path optimizations of the JVM. But when Scala and Clojure compile into Java bytecode, the code “shape”–the way that the programs are laid out in memory–is not the same as when Java programs compile into Java bytecode. Executing bytecode that comes from Scala will have certain performance penalties relative to a functionally identical program written in Java.

GraalVM is a system for interpreting languages into Java bytecode that can run efficiently on the JVM. Any language can be interpreted into an abstract syntax tree that the GraalVM can execute using the JVM. Languages that can run on GraalVM include JavaScript, R, Ruby, and Python.

Thomas Wuerthinger is a senior research director at Oracle and the project lead for GraalVM. He joins the show to explain the motivation for GraalVM, the architecture of the project, and the future of language interoperability. It was an exciting discussion and I learned a lot about the Java ecosystem.

", + "Episodes Title": "GraalVM with Thomas Wuerthinger", + "Episodes Uid": "SED7974872837", + "Episodes Audio File": "ab7570d505dbbc40f21f3ce47af354d8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3fs", + "Episodes ID": "f4a0fa2c-e328-11ea-91a2-ebdf58b9a938", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_25_SeanMcKenna.mp3", + "Episodes Pubdate Date": "2018-01-25", + "Episodes Summary": "

After two weeks of episodes about Kubernetes, our in-depth coverage of container orchestration is drawing to a close. We have a few more shows on the topic before we move on to covering other aspects of software. If you have feedback on this thematic format (whether you like it or not), send me an email: jeff@softwareengineeringdaily.com

Today’s episode fits nicely into some of the themes we have covered recently–Cloud Foundry, Kubernetes, and the changing landscape of managed services. Sean McKenna works on all three of these things at Microsoft.

We spent much of our time discussing the use cases of container instances versus Kubernetes. Container instances are individual managed containers–so you could spin up an application within a container instance without having to deal with the Kubernetes control plane. Container instances might be described as “serverless containers,” since you do not have to program against the underlying VM at all.

This begs the question–why would you want to use a managed Kubernetes service if you could just use individual managed containers? Sean explores this question, and gives his thoughts on where this ecosystem is headed. Full disclosure: Microsoft is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless Containers with Sean McKenna", + "Episodes Uid": "SED9320209223", + "Episodes Audio File": "d0bd4b78481d298773bae0af974dae29.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3zs", + "Episodes ID": "f2975c26-e328-11ea-91a2-0f0ed3d15289", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_19_RustandTokio.mp3", + "Episodes Pubdate Date": "2018-06-19", + "Episodes Summary": "

Rust is a systems programming language with a distinct set of features for safety and concurrency. In previous shows about Rust, we explored how Rust can prevent crashes and eliminate data races through its approach to type safety and memory management.

Rust’s focus on efficiency and safety makes it a promising language for networking code. Tokio is a set of networking libraries built on Rust. Tokio enables developers to write asynchronous IO operations by way of its multithreaded scheduler. Tokio’s goal is to make production-ready clients and servers easy to create by focusing on small, reusable components.

Carl Lerche is an engineer at Buoyant, a company that makes the popular Linkerd and Conduit service mesh systems. Kubernetes developers deploy service mesh to their distributed applications as sidecar proxies. These proxies need to be low-latency and highly reliable. In that light, it makes sense that Conduit (the more recent service mesh from Buoyant) is built using Rust. Carl joins the show to describe why Rust is useful for building networked services.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Rust Networking with Carl Lerche", + "Episodes Uid": "SED4788081755", + "Episodes Audio File": "e21ee3c785319f4d5254f7b3394cd6e1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ma", + "Episodes ID": "f3bf1468-e328-11ea-91a2-335268795a8e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_28_Plasma.mp3", + "Episodes Pubdate Date": "2018-03-28", + "Episodes Summary": "

Ethereum is a system for running decentralized smart contracts. In the current implementation of Ethereum, every smart contract gets deployed to every full node. Whenever a user wants to call a smart contract, that smart contract gets executed on each full node–across the entire network.

The current model for smart contract execution needs to be made more scalable. In today’s episode, Christian Reitwiessner joins the show to describe Plasma–a system for scaling smart contracts. Christian is a developer who has worked extensively on Solidity, the most popular smart contract programming language in Ethereum.

For the last month, we have focused on blockchain related topics, and we will soon be shifting to other subjects. Some of the listeners have not enjoyed the blockchain focus, other people have loved it–for everyone listening, we would love for you to fill out our listener survey at softwareengineeringdaily.com/survey. This will help us decide what other content to focus on.

Of course–you can also send me an email at any time, jeff@softwaredaily.com. And join our Slack at softwareengineeringdaily.com/slack. And if you are completely sick of cryptocurrencies, check out our back catalog of episodes at softwaredaily.com, or by downloading our apps, which have all of our episodes including our Greatest Hits, which is a curated set of the most popular shows. The apps will soon have offline downloads and bookmarking.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Plasma: Smart Contract Scalability with Christian Reitwiessner", + "Episodes Uid": "SED5365642187", + "Episodes Audio File": "b005a075ea454c9c084b4afda307d541.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4w1", + "Episodes ID": "f0a097a2-e328-11ea-91a2-07953aae3dcd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_08_MapillaryResearch.mp3", + "Episodes Pubdate Date": "2018-11-08", + "Episodes Summary": "

Mapillary is a company that processes high volumes of images to develop a labeled 3-D model of the physical world. Mapillary’s APIs allow developers to build applications that are aware of stop signs, buildings, streets, trees, and other physical objects in real-world space. The potential use cases for Mapillary are numerous, ranging from self-driving cars to augmented reality.

We can now build a 3-D model of the real world. It’s not a perfect representation of reality, but it is much better than we had just a few years ago. What has changed? How have the tools advanced such that we are able to build an API for accessing accurate information about the physical world around us?

Mapillary is possible because of a combination of modern developments.

High quality smartphone cameras enable users to crowdsource images of the world around them. Cloud computing allows for cheap workload processing. Newer computer vision techniques allow 2-D images to be stitched together in a 3-D representation. Deep learning architectures improve the classification and segmentation of objects in an image.

Peter Kontschieder is the head of research at Mapillary, and he joins the show to talk about the technologies and research that has enabled Mapillary to build a futuristic business–an API for accessing information about the physical world.

Software Engineering Daily is looking for sponsors. If you are interested in reaching over 50,000 developers, you can go to softwareengineeringdaily.com/sponsor to find out more, and you can send us a message. We’d love to hear from you. And if you are an engineer working at a company that is marketing to developers, or hiring developers, if you tell your marketing department or your recruiting department about softwareengineeringdaily.com/sponsor, that is one way to help us out.

", + "Episodes Title": "Computer Vision with Peter Kontschieder", + "Episodes Uid": "SED9199217932", + "Episodes Audio File": "f1a4a239e2f67d327a5ece1b7a24760d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ow", + "Episodes ID": "f352d83e-e328-11ea-91a2-ff4380e1e13b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_27_KubernetesClusterManagement.mp3", + "Episodes Pubdate Date": "2018-04-27", + "Episodes Summary": "

Google’s central system for managing compute resources is called Borg. On Borg, millions of Linux containers process a wide variety of workloads. When a new application is spun up, Borg provides that application with the resources it needs.

Workloads at Google usually fall into one of two distinct categories: long-running application workloads (such as Gmail) and batch workloads (such as a MapReduce job). In the early days of Google, the long-lived workloads were scheduled onto a system called “BabySitter” and the batch workloads were scheduled onto a system called “Global Work Queue.”

Borg was the first cluster manager at Google designed to service both long-running and batch workloads from a single system. The second cluster manager at Google was Omega, a project that was created to improve the engineering behind Borg. The innovations of Omega improved efficiency and architecture of Borg.

More recently, Kubernetes was created as an open source implementation of the ideas pioneered in Borg and Omega. Google has also built a Kubernetes as a service offering that companies use to run their infrastructure in the same way that Google does.

Brian Grant is an engineer at Google who has seen the iteration of all three cluster management systems that have come out of Google. He joins the show to discuss how the workloads at Google have changed over time, and how his perspective on how to build and architect distributed systems has evolved. Full disclosure: Google is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Google Cluster Evolution with Brian Grant", + "Episodes Uid": "SED5844871156", + "Episodes Audio File": "b75429f698118dacd36e74c6c732e9fd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2v7", + "Episodes ID": "f73f0fda-e328-11ea-91a2-ffac5c1ad927", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Rubrik.mp3", + "Episodes Pubdate Date": "2017-07-18", + "Episodes Summary": "

Every software company backs up critical data sources. Backing up databases is a common procedure, whether a company is in the cloud or on-prem. Backing up virtual machine instances is less common.

Rubrik is a company that is known for building backup infrastructure for enterprises. Their main product is an appliance that sits on prem at an enterprise and stores snapshots of virtual machines running within the enterprise. If a virtual machine dies, Rubrik can quickly restore the VM snapshot. The appliance also backs up to the cloud.

Kenny To is a founding engineer at Rubrik, and he joins the show to discuss backups and how Rubrik is engineered. Enterprises that start backing up to the cloud through Rubrik start a path towards potentially more cloud services. For enterprises that have not been able to move to the cloud yet, this can be an appealing opportunity.

Software Engineering Daily is looking for sponsors for Q3. If your company has a product or service, or if you are hiring, Software Engineering Daily reaches 23,000 developers listening daily. Send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Backups with Kenny To", + "Episodes Uid": "SED5706446260", + "Episodes Audio File": "f93b8b6acab67d035468f0d6cc5c7446.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "71z", + "Episodes ID": "e9dec268-e328-11ea-91a2-a37a98293a60", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_06_GodotGameEngine.mp3", + "Episodes Pubdate Date": "2020-04-06", + "Episodes Summary": "

Building a game is not easy. The development team needs to figure out a unique design and gameplay mechanics that will attract players. There is a great deal of creative work that goes into making a game successful, and these games are often built with low budgets by people who are driven by the art and passion of game creation.

A game engine is a system used to build and run games. Game engines let the programmer work at a high level of abstraction, by providing interfaces for graphics, physics, and scripting. Popular game engines include Unreal Engine and Unity, both of which require a license that reduces the amount of money received by the game developer.

Godot is an open source and free to use game engine. The project was started by Juan Linietsky, who joins the show to discuss his motivation for making Godot. We have done some great shows on gaming in the past, which you can find on SoftwareDaily.com. Also, if you are interested in writing about game development, we have a new writing feature that you can check out by going to SoftwareDaily.com/write.

", + "Episodes Title": "Godot Game Engine with Juan Linietsky", + "Episodes Uid": "SED2929256238", + "Episodes Audio File": "cb36974366ea008e7cc073f118dd574e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6hl", + "Episodes ID": "eb4e3944-e328-11ea-91a2-8795bcd947d4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_05_IstioMarketStrategy.mp3", + "Episodes Pubdate Date": "2019-12-05", + "Episodes Summary": "

Kubernetes has created a widespread system for deploying and managing infrastructure. As Kubernetes has been increasingly adopted, companies are thinking about how to leverage that common layer of infrastructure. With the common infrastructure abstraction of Kubernetes, it becomes easier to adopt other abstractions that are uniform across the entire company. 

This has created a market opportunity for products such as a service mesh.

A service mesh consists of sidecar containers that get deployed alongside services in a distributed system. Each sidecar container is used as a proxy for all the communication that goes through the service it is deployed with. This consistent proxying layer provides each service with benefits such as security, routing, telemetry, and policy management.

Istio is a service mesh that was created and open sourced by Google. Istio is built around the Envoy service proxy sidecar and a control plane that manages the Envoy sidecars. Since the launch of Istio, some of the Google employees who were working on Istio have started Tetrate, a company with the goal of commercializing Istio into a product that enterprises will pay for.  

The market demand for service mesh has been proven, but there are many competitors to Tetrate. Istio is open source and can be commercialized by other companies, as well as cloud providers such as Google and AWS. Linkerd is a service mesh built by the company Buoyant, which was the first company to focus exclusively on this space. There are other companies that are expanding existing products into service mesh: Kong, NGINX, and Hashicorp.

Zack Butcher is a founding engineer with Tetrate, and he joins the show to discuss the market for service mesh and the plan for Tetrate to build a business around Istio.

", + "Episodes Title": "Istio Market Strategy with Zack Butcher", + "Episodes Uid": "SED4058623339", + "Episodes Audio File": "81977a1eb464ea4948e713a4f835a04b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "20u", + "Episodes ID": "1ad4adce-e329-11ea-91a2-fb9f9782039f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Azure-iot_Edited.mp3", + "Episodes Pubdate Date": "2016-06-17", + "Episodes Summary": "

The Internet of Things is becoming a reality. Factories are being outfitted with sensors, temperature monitors, and other data gathering devices. In agriculture, farms are becoming more efficient thanks to soil monitoring devices and automated pesticide regulation. In our homes, refrigerators, alarm clocks, and mirrors are becoming “smart”.

Steve Busby joins the show today to talk about the big picture: how the Internet of things works, from data ingestion to processing to feedback. Steve works at Microsoft in the Azure IoT division, and he discusses the problems which companies are having and the solutions that are available today–and where we are going in the future.

", + "Episodes Title": "Internet of Things with Azure’s Steve Busby", + "Episodes Uid": "SED1189377135", + "Episodes Audio File": "7cbc122a331e0c23d27b1fec5744fc17.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6bl", + "Episodes ID": "ebf23d00-e328-11ea-91a2-2f5d053ee098", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_18_LinkedinKafka.mp3", + "Episodes Pubdate Date": "2019-10-18", + "Episodes Summary": "

Apache Kafka was created at LinkedIn. Kafka was open sourced in 2011, when the company was eight years old. By that time, LinkedIn had developed a social network with millions of users. LinkedIn’s engineering team was building a range of externally facing products and internal tools, and many of these tools required a high-throughput system for publishing data and subscribing to topics.

Kafka was born out of this need. Over time, Kafka’s importance within LinkedIn has only grown. Kafka plays a central role for services, log management, data engineering, and compliance. LinkedIn might be the biggest user of Apache Kafka in the entire software industry. Kafka has many use cases, and it is likely that they are almost all on display within LinkedIn.

Nacho Solis is a senior software engineering manager at LinkedIn, where he helps teams build infrastructure for Kafka, as well as Kafka itself. Nacho joins the show to discuss the history of Kafka at LinkedIn, and the challenges of managing such a large deployment of Kafka. We also talk about streaming, data infrastructure, and more general problems in the world of engineering management.

Full disclosure: LinkedIn is a sponsor of Software Engineering Daily.

", + "Episodes Title": "LinkedIn Kafka with Nacho Solis", + "Episodes Uid": "SED6652277128", + "Episodes Audio File": "803ec5c16fb167a70c138ea75322fad8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ac", + "Episodes ID": "e9138486-e328-11ea-91a2-679ea5ede09b", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_02_HolocleanDataCleaning.mp3", + "Episodes Pubdate Date": "2020-06-02", + "Episodes Summary": "

Many data sources produce new data points at a very high rate. With so much data, the issue of data quality emerges. Low quality data can degrade the accuracy of machine learning models that are built around those data sources. Ideally, we would have completely clean data sources, but that’s not very realistic. One alternative is a data cleaning system, which can allow us to clean up the data after it has already been generated.

HoloClean is a statistical inference engine that can impute, clean, and enrich data. HoloClean is centered around “The Probabilistic Unclean Database Model”, which allows for two systems–an “intension” and a “realizer” to work together to fill in missing fields and fix erroneous fields in data.

HoloClean was created by Theo Rekatsinas, and he joins the show to talk about the problem of fast, unclean data, and his work with HoloClean. We also talk about other problems in machine learning and the engineering workflows around data.

", + "Episodes Title": "HoloClean: Data Quality Management with Theodoros Rekatsinas", + "Episodes Uid": "SED9047131417", + "Episodes Audio File": "ca374adc63e8b2a60480e3d02760d487.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "18s", + "Episodes ID": "26558f1a-e329-11ea-91a2-2b841d219518", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Languages_Edited_2.mp3", + "Episodes Pubdate Date": "2016-01-06", + "Episodes Summary": "

Brian Kernighan is a professor of computer science at Princeton University and the author of several books, including “The Go Programming Language” and “The C Programming Language”, a book more commonly referred to as K&R. Professor Kernighan also worked at Bell Labs alongside Unix creators Ken Thompson and Dennis Ritchie and contributed to the development of Unix.

", + "Episodes Title": "Language Design with Brian Kernighan", + "Episodes Uid": "SED8783603439", + "Episodes Audio File": "a2282f4026a6c39a8d49381491ecfca6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "rb", + "Episodes ID": "304480bc-e329-11ea-91a2-0391779d1dd4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/prah_mimir.mp3", + "Episodes Pubdate Date": "2015-10-07", + "Episodes Summary": "

It provides automated code grading, plagiarism checking, code quality analysis and additional course management tools.

Prah Veluvolu is the CEO and Co-founder of Mimir. He studied at Purdue University and participated in the Boiler Startup Accelerator before graduating from the Y Combinator Summer 2015 class.

", + "Episodes Title": "Automating the CS Classroom with Prah Veluvolu", + "Episodes Uid": "SED4946953806", + "Episodes Audio File": "90814941ab90d3fb84762041b19b2c61.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1rf", + "Episodes ID": "202d0cf8-e329-11ea-91a2-639b0dcf10e7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Gitter_Edited.mp3", + "Episodes Pubdate Date": "2016-03-22", + "Episodes Summary": "

Software developers have been socializing on chat rooms for decades. In the nineties, we began using IRC and AOL instant messenger. In the early 2000s, we turned to Google Hangouts and Yammer. Today, we are using modern apps like Slack and Hipchat.

On today’s show, we take a deep dive into Gitter, the chat client specifically designed for developers. Our guests are Mike Bartlett and Andrew Newdigate, the creators of Gitter. Gitter is a highly scalable, real time social application for developers to talk about writing their software. This is a great episode that spans topics like front end development, back end distributed systems, how to compete with Slack, and how to scale a chat room to tens of thousands of active users.

", + "Episodes Title": "Gitter Engineering with Mike Bartlett and Andrew Newdigate", + "Episodes Uid": "SED9515854901", + "Episodes Audio File": "5cc097862bd5ebb0e17d9c5b570276cc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6yd", + "Episodes ID": "ea1ff206-e328-11ea-91a2-9f64a579db03", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_17_Sisu.mp3", + "Episodes Pubdate Date": "2020-03-17", + "Episodes Summary": "

A high volume of data can contain a high volume of useful information. That fact is well understood by the software world. Unfortunately, it is not a simple process to surface useful information from this high volume of data. A human analyst needs to understand the business, formulate a question, and determine what metrics could reveal the answer to such a question.

Sisu is a system for automatically surfacing insights from large data sets within companies. A user of Sisu can select a database column that they are interested in learning more about, and Sisu will automatically analyze the records in the database to look for trends and relationships between that column and the other columns. 

For example, if I have a database of user purchases, including how much money those users spent on each purchase, I can ask Sisu to analyze the purchase price column, and find what kinds of attributes correlate with a high purchase price. Perhaps there will be correlations such as age and city that I can use to understand my customers better. Sisu can automatically surface these correlations and display them to me to help me make business decisions.

Peter Bailis is the CEO of Sisu Data and an assistant professor at Stanford. Peter joins the show to give his perspective on the development of Sisu, which came out of his research on data-intensive systems, including MacroBase, an analytic monitoring engine that prioritizes human attention.

", + "Episodes Title": "Sisu Data with Peter Bailis", + "Episodes Uid": "SED3322777696", + "Episodes Audio File": "b1284ec81fcfd6f20a87caed7bad6424.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ei", + "Episodes ID": "23c85750-e329-11ea-91a2-efbd8b5a0921", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/hadoop_history_edited.mp3", + "Episodes Pubdate Date": "2016-02-06", + "Episodes Summary": "

This episode is different from the traditional interview format of Software Engineering Daily, and focuses on the history of Hadoop. Thanks to Marco Bonaci for allowing us to republish this in audio format.

You can find the original post here: History of Hadoop

", + "Episodes Title": "The History of Hadoop", + "Episodes Uid": "SED7857571961", + "Episodes Audio File": "64a75177deca44510b16fb5e40a840bf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ct", + "Episodes ID": "0e63cc5a-e329-11ea-91a2-ef00b75b2899", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/botpodcast_edited.mp3", + "Episodes Pubdate Date": "2016-12-15", + "Episodes Summary": "

Over the next few years, bots will pervade our lives more and more. These smart, conversational text interfaces provide a new way of engaging with the computer systems that we have been mostly interacting with through web and mobile app interfaces for the last decade.

Bots are a necessary complement to the voice interfaces of the future, because we don’t always want to talk to the computer, and natural language processing is not yet good enough to always translate our vocal request accurately. Bots are not toys, they aren’t trivial, and they aren’t going away any time soon.

Jon Bruner is the host of the O’Reilly Bots Podcast, a show that has quickly become one of my favorites because it covers both theoretical and applied artificial intelligence, while remaining approachable to listen to. Jon hosts it with Pete Skomoroch, who works on a bot startup full time. Jon and Pete were also organizers of O’Reilly Bot Day, which I enjoyed tremendously and got a lot of knowledge from.

", + "Episodes Title": "Bots with Jon Bruner", + "Episodes Uid": "SED1338533440", + "Episodes Audio File": "f470c1d77399c4af44360e0f726aacf5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "15t", + "Episodes ID": "27aa1f8e-e329-11ea-91a2-87b18179f034", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/future_of_js_Edited.mp3", + "Episodes Pubdate Date": "2015-12-22", + "Episodes Summary": "

Eric Elliott is a JavaScript advocate, and the author of Programming JavaScript Applications. He is also an entrepreneur tackling social issues including homelessness and inequality in the tech industry.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "The Future of JavaScript with Eric Elliott", + "Episodes Uid": "SED9427474064", + "Episodes Audio File": "630a700b766a28cb1fd153e7cd45b6f6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7d4", + "Episodes ID": "e8ba6126-e328-11ea-91a2-0b1505b03248", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_30_Cresta.mp3", + "Episodes Pubdate Date": "2020-06-29", + "Episodes Summary": "

At a customer service center, thousands of hours of audio are generated. This audio provides a wealth of information to transcribe and analyze. With the additional data of the most successful customer service representatives, machine learning models can be trained to identify which speech patterns are associated with a successful worker.

By identifying these speaking patterns, a customer service center can continuously improve, with the different representatives learning the different patterns. The same is true for other speech-based tasks, such as sales calls.

Cresta is a company that builds systems to ingest high volumes of speech data in order to discover features that correlate with high performance human workers. Zayd Enam is a co-founder of Cresta, and joins the show to talk about the domain of speech data and what he and his team are building at Cresta.

", + "Episodes Title": "Cresta: Speech ML for Calls with Zayd Enam", + "Episodes Uid": "SED2402578441", + "Episodes Audio File": "56499d7179b3a7e16f6f450addfdbbaa.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "69r", + "Episodes ID": "ec25bd2e-e328-11ea-91a2-ab6752dc96fb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_03_MessyMiddle.mp3", + "Episodes Pubdate Date": "2019-10-03", + "Episodes Summary": "

Scott Belsky founded Behance in 2006. Behance is a social platform where designers and creators share their work.

Scott was motivated to start Behance due to his desire to combine his love for creativity with his desire to create a business. After 6 years of work, Behance was acquired by Adobe for more than $150 million. Today, Scott works as the Chief Product Officer at Adobe.

Behance’s journey from idea to acquisition is told by Scott in his book The Messy Middle. His book chronicles the difficult, winding journey that an entrepreneur must take in order to succeed, and contains some harrowing stories. Scott has a gritty personality, which was required to endure the ups and downs of Behance.

Scott joins the show to discuss the story of Behance, and the lessons of his life as an entrepreneur. 

", + "Episodes Title": "The Messy Middle with Scott Belsky", + "Episodes Uid": "SED8933313889", + "Episodes Audio File": "9121fd21ad219307dbd5004efa1e81ce.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "26l", + "Episodes ID": "149cfdbc-e329-11ea-91a2-374f3608f7d7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CloudClients_edited.mp3", + "Episodes Pubdate Date": "2016-09-20", + "Episodes Summary": "

Google builds cloud services for developers, such as PubSub, Cloud Storage, BigQuery, and Cloud DataStore. On Software Engineering Daily, we’ve done lots of shows about how these types of services are built. In this episode, we are zooming in on the interaction between the developer using a cloud service and the design and engineering of the client APIs.
\nTo build a useful cloud service, Google has to make a common way of interacting with that service from any programming language on any device. Jon Skeet is a longtime engineer at Google, and he joins the show to explain how Google uses generated code to make the creation of those APIs more streamlined. We talk about gRPC, protocol buffers, C#, and lots of other topics.

", + "Episodes Title": "Cloud Clients with Jon Skeet", + "Episodes Uid": "SED3795817787", + "Episodes Audio File": "d57fddc183c846c4f814a7789a4c064f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 246, + "Episodes ID": "17cf151a-e329-11ea-91a2-e76c930fc7cf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Prometheus_Edited.mp3", + "Episodes Pubdate Date": "2016-08-01", + "Episodes Summary": "

Prometheus is an open-source monitoring tool built at SoundCloud. It can be used to produce detailed time-series data about a distributed architecture. Prometheus is based on the monitoring system inside Google’s infrastructure, called Borgmon.

Julius Volz is the creator of Prometheus, and he joins the show to explain why he built Prometheus and how it differs from previous monitoring tools. Prometheus is widely used to monitor Kubernetes clusters, just like Google uses Borgmon to monitor its Borg clusters.

", + "Episodes Title": "Prometheus with Julius Volz", + "Episodes Uid": "SED7230073374", + "Episodes Audio File": "ba02ae1fccaac4cfc980f52dd354e5e0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1dx", + "Episodes ID": "23cf4fc4-e329-11ea-91a2-13dd09ea2bc8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DO_Edited.mp3", + "Episodes Pubdate Date": "2016-02-05", + "Episodes Summary": "

Operating a data center has been turned into a service. For most new companies, managing real-world servers is no longer an issue. But one exception is if your startup is a company offering the data center as a service. In this episode, Jeff and Sam talk about the engineering that goes on at DigitalOcean, and how the company differentiates itself from its competitors.

Sam Kottler is an engineering manager at DigitalOcean, and previously worked at Red Hat.

", + "Episodes Title": "Engineering Cloud Services with Sam Kottler", + "Episodes Uid": "SED7388543053", + "Episodes Audio File": "0cc623882e494f03193b34bbd906b8f0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7d5", + "Episodes ID": "e8b563d8-e328-11ea-91a2-47f6c894bae3", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_30_Postman.mp3", + "Episodes Pubdate Date": "2020-06-30", + "Episodes Summary": "

A software company manages and interacts with hundreds of APIs. These APIs require testing, performance analysis, authorization management, and release management. In a word, APIs require collaboration.

Postman is a system for API collaboration. It allows users to test APIs with collections of requests, monitor the API responses, and visualize the query results. Users of Postman can collaborate with their team through Team Workspaces, sharing collections, environments, history, and more.

Abhinav Asthana is the founder of Postman and he joins the show to talk about API management and collaboration. Abhinav started Postman as a hobby project, and it has grown into a large and successful business, far beyond the original product of API testing.

", + "Episodes Title": "Postman: API Development with Abhinav Asthana", + "Episodes Uid": "SED8188255962", + "Episodes Audio File": "876e86669428df65713e1360e6747446.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7iv", + "Episodes ID": "61301e48-e3f1-11ea-914a-c300e201becd", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_21_ReleaseApp.mp3", + "Episodes Pubdate Date": "2020-08-21", + "Episodes Summary": "

Every software company works off of several different development environments–at the very least there is staging, testing, and production. Every push to staging can be spun up as an application to be explored, tinkered with, and tested. These ad hoc spin-ups are known as release apps.

A release app is an environment for engineers to play with, and potentially throw away or promote to production. Release apps have been made easier due to technologies such as infrastructure-as-code, continuous integration, and Kubernetes.

Tommy McClung is the co-founder of Release App, a company that makes it easy to spin up release environments for your software. Tommy joins the show to discuss release workflows, and his work building Release App.

", + "Episodes Title": "Release Apps with Tommy McClung", + "Episodes Uid": "SED9816944690", + "Episodes Audio File": "29d74f18a79aa4b505107232cdce6e47.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "76s", + "Episodes ID": "e970f666-e328-11ea-91a2-2fdf8f61b14a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_05_06_RedisLabs.mp3", + "Episodes Pubdate Date": "2020-05-06", + "Episodes Summary": "

Redis is an in-memory object storage system that is commonly used as a cache for web applications. This core primitive of in-memory object storage has created a larger ecosystem encompassing a broad set of tools. Redis is also used for creating objects such as queues, streams, and probabilistic data structures.

Machine learning systems also need access to fast, in-memory object storage. RedisAI is a newer module for supporting machine learning tasks. For serverless computing, RedisGears allows for the execution of functions close to your Redis instance. RedisEdge allows for edge computing with Redis.

Alvin Richards returns to the show to discuss the expansion of Redis to becoming a broad suite of in-memory tools, as well as the resiliency properties of Redis and usage patterns for the tool. RedisLabs is a sponsor of Software Engineering Daily, and RedisConf is a virtual conference around Redis that runs May 12-13. If you are interested in Redis, you can check out RedisConf for free by going to RedisConf.com.

", + "Episodes Title": "Advanced Redis with Alvin Richards", + "Episodes Uid": "SED9230368842", + "Episodes Audio File": "1165031397753ca9427308eec1b66e3b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6qx", + "Episodes ID": "ea9b05ea-e328-11ea-91a2-83a7c11754c1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_11_DruidJadNaous.mp3", + "Episodes Pubdate Date": "2020-02-11", + "Episodes Summary": "

Large companies generate large volumes of data. This data gets dumped into a data lake for long-term storage, then pulled into memory for processing and analysis. Once it is in memory, it is often read into a dashboard, which presents a human with a visualization of the data. 

The end-user who is consuming this data is often a data scientist who is looking at the data to find trends and design new machine learning models. Another kind of user is the operational analyst. An operational analyst is creating complex queries across this data to find latencies in the infrastructure, or perhaps slicing and dicing clickstream data that is coming from online advertisements, in order to figure out how to tweak those advertising algorithms and spend money more effectively.

For an operational analyst, a key use case for a data warehouse is fast, interactive querying. The operational analyst needs to be able to query the data to quickly create a dashboard, make judgments based on that dashboard, and then change the query slightly to look at a slightly different dashboard.

Druid is a high-performance database that is used for these kinds of queries. Druid is used for ad-hoc queries and operational analytics. Imply Data is a company that builds visualization, monitoring, and security around Druid. Jad Naous is vice president of R&D for Imply, and he joins the show to talk about the use case for Druid, the architecture, and the business model of Imply.

If you enjoy the show, you can find all of our past episodes about data infrastructure by going to SoftwareDaily.com and searching for the technologies or companies mentioned. And if there is a subject that you want to hear covered, feel free to leave a comment on the episode, or send us a tweet @software_daily.

", + "Episodes Title": "Druid Analytics with Jad Nauous", + "Episodes Uid": "SED5295142477", + "Episodes Audio File": "d3dd07fb16dc51317da68b20b67815e3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "72z", + "Episodes ID": "e9bff52c-e328-11ea-91a2-53181445765a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_15_ShopifyReactNative.mp3", + "Episodes Pubdate Date": "2020-04-15", + "Episodes Summary": "

Shopify is a platform for selling products and building a business. It is a large e-commerce company with hundreds of engineers and several different mobile apps. Shopify’s engineering culture is willing to adopt new technologies aggressively, trying new tools that might provide significant leverage to the organization.

React Native is one of those technologies. React Native can be used to make cross-platform mobile development easier by allowing code reuse between Android and iOS. React Native was developed within Facebook, and has been adopted by several other prominent technology companies, with varying degrees of success. 

Many companies have seen improvements to their mobile development and release process. However, in a previous episode, we talked with Airbnb about their adoption of React Native, which was less successful.

Farhan Thawar is a VP of engineering at Shopify. He joins the show to talk about Shopify’s experience using React Native, the benefits of cross-platform development, and his perspective on when it is not a good idea to use React Native.

", + "Episodes Title": "Shopify React Native with Farhan Thawar", + "Episodes Uid": "SED8555355275", + "Episodes Audio File": "8a9b7d54a7b0bdf33e338c86409cd264.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ar", + "Episodes ID": "101d7dd4-e329-11ea-91a2-9fd2b65f8c03", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/geode_edited.mp3", + "Episodes Pubdate Date": "2016-11-21", + "Episodes Summary": "

There is a hierarchy of ways to access and store data in a computer system. The cheapest, slowest way to store and retrieve data is disk. On the faster end, we have memory. As we architect systems with increasing complexity, we have additional considerations–network latency, transient compute nodes, and numerous caching layers.

Apache Geode is a distributed, in-memory system for the JVM. It provides fast data storage and retrieval. Swapnil Bawaskar is an engineer who works on Geode, and he joins the show today to explain the architecture of Geode, and how Geode is different from other in-memory systems that get used for caching, such as memcache or Redis.
\n

", + "Episodes Title": "Apache Geode with Swapnil Bawaskar", + "Episodes Uid": "SED7068677759", + "Episodes Audio File": "a8b4912a5af67d32272e5e2daa146384.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "13q", + "Episodes ID": "29248188-e329-11ea-91a2-6f23c9fe533d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Spotify_Edited_1.mp3", + "Episodes Pubdate Date": "2015-12-11", + "Episodes Summary": "

Spotify is a streaming music service that uses data science and machine learning to implement product features such as recommendation systems and music categorization, but also to answer internal questions.

Boxun Zhang is a data scientist at Spotify where he focuses on understanding user behavior within the product.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Data Science at Spotify with Boxun Zhang", + "Episodes Uid": "SED8764699600", + "Episodes Audio File": "999a03c71735c6a5b727b224ec8dc3cd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6f1", + "Episodes ID": "eb9e7bca-e328-11ea-91a2-0b77845e9764", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_13_BugsnagBusiness.mp3", + "Episodes Pubdate Date": "2019-11-13", + "Episodes Summary": "

Crash monitoring emerged as a software category over the last decade.

Crash monitoring software allows developers to understand when their applications are crashing on client devices. For example, we have an app for Software Engineering Daily that people download on Android or iOS. Users download the app to their smartphone. When the user is playing an episode, and the app crashes, the details of the crash are sent to a server that collects all of these crash reports.

Crash reports allow a company to understand where their application is breaking on client devices. This is important, since there are so many client surfaces to test, from iOS to Android to browsers.

As a business, crash monitoring is a category that has some similarities to log management. There are lots of companies that offer crash monitoring. At first glance, it seems like a simple problem to solve. It seems like a market without winner-take-all or winner-take-most dynamics. But at scale, crash monitoring becomes a deeply complex engineering problem. From indexing to database choices to complex distributed systems tradeoffs, crash monitoring is not a simple business, and it promises to provide an extremely good business for the few companies who are able to out-execute the crowded market.

James Smith is the CEO of Bugsnag, a company that makes crash monitoring and application stability tools. James returns to the show to discuss the growth-stage engineering challenges of error monitoring, and the business opportunities that come with them.

", + "Episodes Title": "Bugsnag Business with James Smith", + "Episodes Uid": "SED1867847140", + "Episodes Audio File": "edc757db89a803f869771973b5463513.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6bj", + "Episodes ID": "ebfc5952-e328-11ea-91a2-03681743d0c8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_16_IncidentReproductionwithTammyButow.mp3", + "Episodes Pubdate Date": "2019-10-16", + "Episodes Summary": "

Databases go offline. Services fail to scale up. Deployment errors can cause an application backend to get DDoS’d.

When an event happens that prevents your company from operating as expected, it is known as an incident. Software teams respond to an incident by issuing a fix. Sometimes that fix returns the software to its ideal state. Other times the software remains in a degraded state, and it takes more fixing to return the software to the place it should be.

One way that a software team can learn from an incident is through incident reproduction. When an incident is turned into a reproducible system, it becomes a predictable training exercise rather than a surprising and painful outage.

Tammy Butow is an engineer with Gremlin, a company that makes chaos engineering software. Chaos engineering is the process of creating controlled experiments that simulate outages. Tammy joins the show to discuss common incident types, and how those can be made reproducible for training exercises.

", + "Episodes Title": "Incident Reproduction with Tammy Butow", + "Episodes Uid": "SED9858195371", + "Episodes Audio File": "6db396e4d2267fe6d002bf9f3ca9b36d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "79b", + "Episodes ID": "e92ff18e-e328-11ea-91a2-9ff514601d93", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_16_softwaredaily_episode.mp3", + "Episodes Pubdate Date": "2020-05-23", + "Episodes Summary": "

For the last five months, we have been working on a new version of Software Daily, the platform we built to host and present our content. 

We are creating a platform that integrates the podcast with a set of other features that make it easier to learn from the audio interviews. 

Software Daily includes the following features:


\nThe world of software is large, and growing bigger every day. Software Daily is a place to explore this world of software companies and projects.

If the podcast is a useful resource for you to learn about software, then Software Daily might also provide you with value. This post (and episode) is a brief description of the features that we have built into Software Daily.

If you want to listen to Software Engineering Daily without ads, you can become a paid subscriber, paying $10/month or $100/year by going to softwaredaily.com/subscribe. We now have an RSS feed that paid customers can add to a podcast player like Overcast (on iOS) or Podcast Addict (on Android). You can also listen to the premium episodes using our apps for iOS or Android.

Whether you are a listener who is fine with listening to ads, or you are a listener who pays to hear episodes without ads, we are happy to have you tuning in.

Apple podcasts limits the number of episodes in an RSS feed to 300. The feed with the last 300 episodes is available by searching for Software Daily. In total, we have more than 1200 episodes in our back catalog.

Listeners often want to find all our episodes on React, or Kubernetes, or serverless, or self-driving cars. We have been covering these topics for years, and much of the old content has retained its value. Software Daily allows you to easily find all the episodes relating to a subject that you are interested in.

You can also find our most popular episodes, ranked by how people interact with them.

Additionally, episode transcripts have interactive features with highlighting, commenting, and discussions. We want to create a Medium-like experience for the episodes.

Software Daily is a place where listeners can write about the topics they are listening to. When you are listening to lots of episodes about a topic such as GraphQL, you may find it useful to write about that topic as a form of active learning. The topic pages also have a Q&A section. Post questions about a topic, or post an answer. Engage in the community dialogue surrounding a topic you are passionate or curious about. If there is a topic you want to write about, check out softwaredaily.com/write.

We will be turning the best written content into short podcast episodes published on the weekends where we will read your contribution and mention your name. If you write something awesome, we want to turn it into audio for larger distribution. 

Every topic on Software Daily has a Q&A section. We have covered lots of niche software companies and open source projects, and on Software Daily we want to collect more information about the world of software with Q&A.

If you want to write about a specific company or topic that you heard about on Software Daily, Q&A is also an option. Our goal with Q&A is to provide a companion experience to listening to the podcast. It is not always easy to retain what you hear in a podcast episode. Answering some questions after you listen to an episode can help with that retention.

Are you looking to hire someone specific in the world of software? Post a job on the Software Daily jobs board. We will be announcing some of these jobs on the podcast, especially the more interesting postings, and ones that align with content we are producing.

We appreciate you tuning into Software Daily. We would welcome your feedback, and hope you take the time to check out SoftwareDaily.com.

", + "Episodes Title": "Software Daily", + "Episodes Uid": "SED5186875071", + "Episodes Audio File": "dbd7cbefd65ad152fef6b06b470c8af7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "67c", + "Episodes ID": "ec540f6c-e328-11ea-91a2-8b2448e27876", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_19_VMwareOSSDirkHohndel.mp3", + "Episodes Pubdate Date": "2019-09-19", + "Episodes Summary": "

Open source software is very new. Open source has existed for less than 30-40 years, depending on who you ask. The idea of open source was popularized by Linux, and open source software started to get heavily commercialized in the 1990s.

By the early 2000s, open source was used by nearly every large software company. In recent years, most of the new databases, web frameworks, user interface libraries, and other software primitives are being built in the open.

Dirk Hohndel is VP and chief open source officer at VMware, where he works on strategies around Linux, containers, Kubernetes, and other open source software. Dirk joins the show to talk about his long history with open source and the current state of the open source ecosystem.

", + "Episodes Title": "Open Source Ecosystem with Dirk Hohndel", + "Episodes Uid": "SED5611341453", + "Episodes Audio File": "a5d2c294e9fe59036aad0e36b56263a8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1n9", + "Episodes ID": "22660024-e329-11ea-91a2-278ba38cc4f6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Neuroscience_Edited.mp3", + "Episodes Pubdate Date": "2016-02-26", + "Episodes Summary": "

Apache Spark is replacing MATLAB in the domain of computational neuroscience. The constraints of running MATLAB on a single machine can’t support the demands of neuroscience, which has huge collections of images and time-series data sets.

Jeremy Freeman is a computational neuroscientist who is adopting Apache Spark to be able to analyze these giant data sets that do not fit on a single machine. But Apache Spark was not designed with neuroscience in mind. For this reason, Jeremy has helped to build several libraries on top of Spark. Thunder is a library for standard, distributed representation of data. Lightning is an API for reproducible web visualizations. These abstractions sit on top of Spark, and add a layer of usability. As it turns out, solving these problems for neuroscience have produced tools that are useful in a variety of other domains. In our discussion with Jeremy Freeman, we talk about Apache Spark, neuroscience, and the technological and cultural problems faced by traditional academic research.

", + "Episodes Title": "Computational Neuroscience with Jeremy Freeman", + "Episodes Uid": "SED7840728218", + "Episodes Audio File": "dcbf3fa704229132969519e62bb561f2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "26c", + "Episodes ID": "14ff9012-e329-11ea-91a2-73e69403d0a6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Commodity_Discussion_Edited.mp3", + "Episodes Pubdate Date": "2016-09-15", + "Episodes Summary": "

A previous episode of Software Engineering Daily called “You Are Not A Commodity” received a lot of feedback, both negative and positive. The episode was a monologue I wrote about why engineers should build products on their own as a default career path, rather than work at a large corporation as a default career path.

A reddit thread about the episode was almost entirely negative. Most of the emails I received about the episode were very positive. Other regular listeners wrote in and said they had mixed feelings. One of those listeners was Preethi Kasireddy, a previous guest of the show.
\nIn this episode, Preethi gives some counterarguments and questions the ideas that were presented in the “You Are Not A Commodity” episode. This will be a useful discussion for anyone who is thinking about their career path, and whether to go work for a company or do something on their own.

", + "Episodes Title": "Commodity Discussion with Preethi Kasireddy", + "Episodes Uid": "SED5401321909", + "Episodes Audio File": "4975799ec21c99a7a6b8c812ac2d770b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1p1", + "Episodes ID": "2198a322-e329-11ea-91a2-9fa726c0939c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/RailsOSS.mp3", + "Episodes Pubdate Date": "2016-03-07", + "Episodes Summary": "

Ruby on Rails has had the most commits made by its creator, David Heinemeier Hansson. The next most frequent contributor to Rails is Aaron Patterson, our guest on today’s episode of Software Engineering Daily. Topics discussed in today’s episode include Ruby relative to JavaScript, Rails relative to Linux, and DHH relative to Tenderlove.

", + "Episodes Title": "Open Source and Rails with Aaron Patterson", + "Episodes Uid": "SED5060495808", + "Episodes Audio File": "1c6a0a00bbc90852d8de106e73afac5f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1p9", + "Episodes ID": "215ec4b8-e329-11ea-91a2-a70973dc8421", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/healthcareML_Edited.mp3", + "Episodes Pubdate Date": "2016-03-08", + "Episodes Summary": "

Diagnosing illness today requires the trained eye of a doctor. With machine learning, we might someday be able to diagnose illness using only a data set. Today on Software Engineering Daily, we are joined by David Kale, a researcher at the intersection of machine learning and clinical data. We discuss the machine learning and research techniques he is using to diagnose illnesses using neural networks, and we also talk about the challenges of performing data science in hospitals, where the data is mostly confidential. David will also be presenting at Strata + Hadoop World in San Jose. We’re partnering with O’Reilly to support this conference – if you want to go to Strata, you can save 20% off a ticket with our code PCSED.

", + "Episodes Title": "Machine Learning in Healthcare with David Kale", + "Episodes Uid": "SED9128058894", + "Episodes Audio File": "9eda414cd4d3fac991d527a541dec948.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6qf", + "Episodes ID": "eaa4f0aa-e328-11ea-91a2-ef428adf8163", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_07_StarburstDataPresto.mp3", + "Episodes Pubdate Date": "2020-02-07", + "Episodes Summary": "

A data platform contains all of the data that a company has accumulated over the years. Across a data platform, there is a multitude of data sources: databases, a data lake, data warehouses, a distributed queue like Kafka, and external data sources like Salesforce and Zendesk.

A user of the data platform often has a question that requires multiple data sources to answer. How does this user join two data sources from a data lake? How does this user join data across a transactional database and a data lake? How does the user join data from two different data warehouse technologies? 

Presto is an open source tool originally developed at Facebook. Presto allows a user to query a data platform with a SQL statement. That query gets parsed and executed across the data platform to read from any heterogeneous data source. For some use cases, Presto is replacing the technology Hadoop MapReduce-based technology Hive. For other use cases, Presto is solving a problem in a completely novel way.

Justin Borgman joins the show to discuss the motivation for Presto, the problems it solves, and the architecture of Presto. He also talks about the company he started, Starburst Data, which sells and supports technologies built around Presto.

If you enjoy the show, you can find all of our past episodes about data infrastructure by going to SoftwareDaily.com and searching for the technologies or companies mentioned. And if there is a subject that you want to hear covered, feel free to leave a comment on the episode, or send us a tweet @software_daily.

", + "Episodes Title": "Presto with Justin Borgman", + "Episodes Uid": "SED8489343305", + "Episodes Audio File": "99492cee688b0320131453dec8fcc225.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6qr", + "Episodes ID": "ea9fd566-e328-11ea-91a2-0f101b31bc0a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_10_DataBenLorica.mp3", + "Episodes Pubdate Date": "2020-02-10", + "Episodes Summary": "

Data infrastructure has been transformed over the last fifteen years. 

The open source Hadoop project led to the creation of multiple companies based around commercializing the MapReduce algorithm and Hadoop distributed file system. Cheap cloud storage popularized the usage of data lakes. Cheap cloud servers led to wide experimentation for data tools. Apache Spark emerged from academia, and Apache Kafka came out of the corporate challenges faced by LinkedIn.

Over these 15 years, Ben Lorica has been following the world of data engineering as an engineer, a conference organizer, and a podcaster. When he was host of the O’Reilly Data Show, his material served as inspiration for some of the episodes of this podcast. Today he hosts The Data Exchange podcast and writes The Data Exchange newsletter. Ben joins the show to talk about modern data engineering, and his opinion on the past and future of data infrastructure.

If you enjoy the show, you can find all of our past episodes about data infrastructure by going to SoftwareDaily.com and searching for the technologies or companies mentioned. And if there is a subject that you want to hear covered, feel free to leave a comment on the episode, or send us a tweet @software_daily.

", + "Episodes Title": "The Data Exchange with Ben Lorica", + "Episodes Uid": "SED8507624614", + "Episodes Audio File": "60d516647f4674e3329ce9d125d2cf85.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6o6", + "Episodes ID": "eac0bb3c-e328-11ea-91a2-af797eba1bd7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_30_AlpacaFinance.mp3", + "Episodes Pubdate Date": "2020-01-30", + "Episodes Summary": "

Stock trading takes place across a variety of software platforms. Etrade and Schwab have allowed individual traders to buy securities for decades. Robinhood built a business around a similar model, but also removed the commission. Wealthfront and Betterment provide “roboadvisor” services that abstract away the underlying securities and focus on managing a risk profile.

Each of these services has a programmatic execution system for managing assets. In order for a developer to build a product like Robinhood or Wealthfront, that developer needs access to an API that can execute trades.

Alpaca is an API for stock trading. Alpaca can be used to build financial products, apps, and algorithmic trading programs. Yoshi Yokokawa is the founder of Alpaca, and he joins the show to talk about why he built an API for trading and the potential applications of Alpaca. Yoshi’s background includes work in finance at Lehman Brothers, a period spent as an individual day trader, and the previous company he started selling custom trading algorithms to enterprises.

", + "Episodes Title": "Alpaca: Stock Trading API with Yoshi Yokokawa", + "Episodes Uid": "SED6555632155", + "Episodes Audio File": "73d99275c0bfb80144000b77a3b57c05.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ia", + "Episodes ID": "22d5b64e-e329-11ea-91a2-33910c8cd5fe", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Design_Edited_2.mp3", + "Episodes Pubdate Date": "2016-02-19", + "Episodes Summary": "

Design is more important than ever. There are so many websites being created every day, that it is not enough to differentiate your product with rock solid engineering. Your product has to be beautiful, intuitive, and tested for usability. You don’t want all of the hard work of the product and engineering teams to go to waste, so on this episode, the focus is design.

Tracy Osborn is the creator of WeddingLovely, a beautifully designed two sided marketplace website, where people who are getting married connect with wedding vendors. Today, Tracy discusses “design for nondesigners”. Whether you are an engineer, a marketer, or a business analyst, just learning a few simple tactics about design can take you far.

", + "Episodes Title": "Design for Non-designers with Tracy Osborn", + "Episodes Uid": "SED8467410919", + "Episodes Audio File": "737384d68bd3048b7e0e30b4a8986214.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1vj", + "Episodes ID": "1ec271fa-e329-11ea-91a2-c3c1f49d2820", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Sumo_Edited.mp3", + "Episodes Pubdate Date": "2016-04-12", + "Episodes Summary": "

Software applications are constantly generating logs. These logs are necessary to understand how an application is functioning, and logs are key to debugging. As applications have gotten more complex, logging infrastructure has become complex as well. Storing and managing all of our log data is such a big task that several companies have been started to tackle this problem.

Today’s guest is Christian Beedgen, CTO at Sumo Logic. Sumo Logic is a cloud-based log management company. We discuss the elastic log-processing platform Sumo Logic has built to help software engineers with log management. It’s a great conversation about distributed systems, machine learning, and debugging applications.

", + "Episodes Title": "Logging and NoOps with Christian Beedgen", + "Episodes Uid": "SED3719233806", + "Episodes Audio File": "fd5383eebd9faa937fcb1caef7aaddd2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1qs", + "Episodes ID": "2076c884-e329-11ea-91a2-df7f74da6e04", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Hired_Edited_2.mp3", + "Episodes Pubdate Date": "2016-03-15", + "Episodes Summary": "

In many ways the engineering job market is broken. Engineers cannot find the right jobs where they are valued properly and enjoy their work. Employers have difficulty filling their positions and finding the right people that fit their cultures. Traditional matchmakers like Monster and generic recruiting agencies don’t cut it — you know this by the generic LinkedIn messages you get looking for a Java expert… when you have JavaScript as a skill on your profile.

Hired.com is trying to fix this broken process by using a high-touch approach to recruiting. Hiten Parmar, an engineer and product strategist at Hired joins us today to discuss the issues at hand, as well as how Hired is approaching the solution. We chat about the challenges facing engineers, which skills are in demand, and the inner workings of Hired. Full disclosure: Hired is a sponsor of the show, but we would still have done this interview because we genuinely want to discuss the job market, and figure out how companies are addressing this issue.

", + "Episodes Title": "The Software Engineering Job Market with Hiten Parmar", + "Episodes Uid": "SED5205152732", + "Episodes Audio File": "41ed1b52d3743ebdfc7b796c9702cd02.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1x6", + "Episodes ID": "1dcc8aec-e329-11ea-91a2-3fe3f145edcd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SYC_Edited_2.mp3", + "Episodes Pubdate Date": "2016-04-28", + "Episodes Summary": "

As software engineering gets more popular, the resources that we use to read and understand software are growing and improving.

Scale Your Code is an organization that seeks to improve accessibility to the world’s programming knowledge, and today’s guest Christophe Limpalair joins me to discuss Scale Your Code. Christophe is a podcaster and blogger who runs Scale Your Code.

", + "Episodes Title": "Scale Your Code with Christophe Limpalair", + "Episodes Uid": "SED3323236520", + "Episodes Audio File": "79c55a0d323378e96a94f6c070669f15.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6g2", + "Episodes ID": "eb823096-e328-11ea-91a2-4f3db51738a4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_21_JuliaEvansHTTP.mp3", + "Episodes Pubdate Date": "2019-11-21", + "Episodes Summary": "

HTTP is a protocol that allows browsers and web applications to communicate across the Internet.

Everyone knows that HTTP is doing some important work, because “HTTP” is at the beginning of most URLs that you enter into your browser. You might be familiar with the request/response model, and HTTP request methods such as GET, PUT, and POST. But unless you have had a reason to learn more about the details of HTTP, you probably don’t know much more than that.

Julia Evans is a software engineer and writer who creates Wizard Zines, a series of easy-to-read online magazines that explain technical software topics. Julia’s zines include “Linux Debugging Tools”, “Help! I Have A Manager!”, and recently “HTTP: Learn your browser’s language”.

Her zines are a creative, innovative format for describing the world of software engineering while also exploring her own artistic pursuits in writing, design, and illustration. Julia was previously on the show to discuss Ruby profiling, and she returns to the show to discuss HTTP, as well as her creative process and goals with Wizard Zines.

", + "Episodes Title": "HTTP with Julia Evans", + "Episodes Uid": "SED6848830261", + "Episodes Audio File": "57aaf42267df81d53228535a66cde18d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 20, + "Episodes ID": "0bc4f65e-e329-11ea-91a2-77c389ed5941", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/meetup_architecture_edited.mp3", + "Episodes Pubdate Date": "2017-01-06", + "Episodes Summary": "

Meetup is an online service that allows people to gather into groups and meet in person. Since 2002, the company has been growing and its technology stack has been changing. Today, they are in the process of migrating to the cloud, using both Amazon Web Services and Google Compute Platform.

Yvette Pasqua is the CTO of Meetup and she joins the show to explain how Meetup’s technology stack works and how the teams are organized. The discussion of multiple clouds is particularly interesting–Yvette describes GCP and AWS as both having distinct, well-defined use cases at Meetup.

", + "Episodes Title": "Meetup Architecture with Yvette Pasqua", + "Episodes Uid": "SED8687038057", + "Episodes Audio File": "5e8e765724cb8977bf834f87804c4386.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2d8", + "Episodes ID": "0de4db16-e329-11ea-91a2-d3d0ff8cbc9a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/adfraudresearch_edited.mp3", + "Episodes Pubdate Date": "2016-12-20", + "Episodes Summary": "

A huge percentage of online advertisements are never seen by humans. They are viewed by bots–automated scripts that are opening web pages in a browser and pretending to be a human. Advertising scammers set up web pages, embed advertisements on those pages, and then pay for bot traffic to come and view those advertisements.

This aspect of the internet is bizarre and alarming. Think about it–how much of the Internet economy depends on online advertising? A lot! How many of those advertisements are consumed by robots? Some estimates say as much as 80%.

The more time I spend looking at the online advertising industry, the more perplexed and curious I become. Augustine Fou also has this curiosity. He got a PhD at MIT in material science and engineering–but today he spends his time researching advertising fraud and working as an independent consultant.

", + "Episodes Title": "Ad Fraud Research with Augustine Fou", + "Episodes Uid": "SED1207988098", + "Episodes Audio File": "50d841b5168e126b65570086e0ef98a5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "14s", + "Episodes ID": "28689ff4-e329-11ea-91a2-33a588f7c063", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Hanselminutes_Edited.mp3", + "Episodes Pubdate Date": "2015-12-16", + "Episodes Summary": "

Scott Hanselman is a technologist, teacher and podcaster who works for Microsoft on its web platform team. Scott hosts several podcasts including Hanselminutes and This Developer’s Life, which cover various topics in software.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Hanselminutes with Scott Hanselman", + "Episodes Uid": "SED1249752868", + "Episodes Audio File": "eed0f2e2f26ac8eb817e0c05197f2acc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7fn", + "Episodes ID": "e877ddb0-e328-11ea-91a2-e3d6f7c0fa41", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_17_ADP.mp3", + "Episodes Pubdate Date": "2020-07-17", + "Episodes Summary": "

ADP has been around for more than 70 years, fulfilling payroll and other human resources services. Payroll processing is a complex business, involving the movement of money in accordance with regulatory and legal strictures. 

From an engineering point of view, ADP has decades of software behind it, and a bright future of a platform company used by thousands of companies. Balancing the maintenance of old code while charting a course with the new projects is not a simple task. 

Tim Halbur is the CTO of ADP, and he joins the show to talk through how engineering works at ADP, and how the organization builds for the future of the company while maintaining the code of the past.

", + "Episodes Title": "ADP Engineering with Tim Halbur", + "Episodes Uid": "SED4188530243", + "Episodes Audio File": "15fdcff59dbc733c8cee79f10bc39095.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 292, + "Episodes ID": "122fce60-e329-11ea-91a2-ab22a36bfede", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/coincenter_edited.mp3", + "Episodes Pubdate Date": "2016-10-27", + "Episodes Summary": "

Blockchain technologies like Bitcoin and Ethereum have not impacted the lives of most consumers today. The theoretical breakthroughs that blockchain enables will eventually happen–I will be able to pay 1 cent to a knowledge worker in Africa without having to pay a 5 cent transaction fee. My servers will be able to pay other servers for small compute jobs. We will have decentralized versions of sharing economy systems like Airbnb and Uber. 

But first there are many infrastructure and policy issues to sort through. The technology is not quite there yet, and people running even simple mining operations are threatened by our current legal framework.

Coin Center is an organization dedicated to education of policymakers and media about blockchain technology. Peter Van Valkenburgh directs research at Coin Center, and joins the show to talk about the issues that stand in the way of that utopian dream of micropayments, IoT, and other blockchain miracles.

", + "Episodes Title": "Coin Center with Peter Van Valkenburgh", + "Episodes Uid": "SED1677475810", + "Episodes Audio File": "c2b6749d3c8bbfa846d18f95ffd68b11.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "14f", + "Episodes ID": "28c70b8e-e329-11ea-91a2-eb68ebebbfa1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/coderdojo_Edited.mp3", + "Episodes Pubdate Date": "2015-12-14", + "Episodes Summary": "

Rebecca Garcia is the creator of GeekGirlWeb and founder of CoderDojo NYC. She spends much of her time educating people about the importance of STEM education, particularly in the domain of programming.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Teaching Kids to Code with Rebecca Garcia", + "Episodes Uid": "SED5061218724", + "Episodes Audio File": "ffd40d8df38adfe58867639b2c7c84c9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5z2", + "Episodes ID": "ed17a79c-e328-11ea-91a2-dbd95903b8c1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_22_EmergingMarketsVietnam.mp3", + "Episodes Pubdate Date": "2019-07-22", + "Episodes Summary": "

From Africa to India to Asia to South America–computer science and programming are rising in popularity in every emerging market. Each of these markets has regional needs for technology. Just like every culture develops its own food and television, every culture needs different types of applications to run their lives.

In Vietnam, the day-to-day life of a citizen is different than it is in the United States. Yes, everyone needs Google and YouTube and Instagram. But the trends in messaging, food delivery, gig economy, and other B2C technology sectors are considerably different than the west.

Charles Lee is the founder of CoderSchool a coding school in Vietnam. Before moving to Vietnam to start CoderSchool, he worked as a software engineer in San Francisco for several years. In today’s show, Charles describes the difference between the US and Vietnamese technology sectors, from consumer applications to business software to coding education.

", + "Episodes Title": "Emerging Markets: Vietnam with Charles Lee", + "Episodes Uid": "SED4653098626", + "Episodes Audio File": "ffe0a87657a1fd8e43595f918618876f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1yz", + "Episodes ID": "1cdb175c-e329-11ea-91a2-6f008e9bc575", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Distributed_Tradeoffs_Edited.mp3", + "Episodes Pubdate Date": "2016-05-16", + "Episodes Summary": "

Distributed systems products are often marketed with terms like “real-time data” and “hassle-free scaling”, but what do those terms actually mean? Is data in a distributed system ever reliably “real time”? Do we ever have strong enough plans about our scalability strategy to say that scaling will be “hassle free”?

Camille Fournier joins us today to discuss distributed systems in practice. Like everything in else in computer science, distributed systems are all about tradeoffs–and picking the right sets of tradeoffs in our distributed system will affect the entire organization that is building that system.

We also discuss the Cloud Native Computing Foundation, which is similar to the Apache Foundation, but specifically for cloud technologies. The CNCF is likely to have strong impact on the way we build software for a long time to come.

", + "Episodes Title": "Distributed Systems Tradeoffs with Camille Fournier", + "Episodes Uid": "SED4597198768", + "Episodes Audio File": "c2bbf820e19c5648230ef0f8a32ad737.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6m9", + "Episodes ID": "eae56fea-e328-11ea-91a2-7be95400e819", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_20_TimOReilly.mp3", + "Episodes Pubdate Date": "2020-01-20", + "Episodes Summary": "

Software has changed the way the world functions. The rapid pace of change has made it difficult to know how to navigate the new world. Knowledge workers who want to keep advancing in their careers develop a strategy of continuous learning in order to adapt to these changes.

O’Reilly Media has existed for almost 40 years, providing resources for the technical consumer. As O’Reilly has expanded its product line from books to conferences to online learning, the business has grown slowly but steadily. That business trajectory stands in contrast to many of the software companies that are financially structured to either grow rapidly or die.

Today, O’Reilly has a large impact on the software ecosystem. Software professionals congregate at O’Reilly conferences. Enterprises pay O’Reilly to educate their employees. And O’Reilly continues to grow into new product lines, recently acquiring the interactive learning platform Katacoda, which can be used to learn about Kubernetes and other popular technologies.

In a previous episode, we discussed Tim O’Reilly’s book “What’s The Future”. In today’s show, Tim returns to the show to discuss his experience building O’Reilly, and how his business philosophy contrasts with much of the assumed wisdom of software company building.

", + "Episodes Title": "Software Media with Tim O’Reilly", + "Episodes Uid": "SED1505100513", + "Episodes Audio File": "e4db3795291682b8277905ce2674c2c2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "16a", + "Episodes ID": "26f7b308-e329-11ea-91a2-7be9bd778764", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Mesos_Edited_2.mp3", + "Episodes Pubdate Date": "2015-12-30", + "Episodes Summary": "

Michael Hausenblas is a developer and cloud advocate with Mesosphere, which builds the Datacenter Operating System (DCOS), a distributed OS that uses Apache Mesos as its kernel.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Mesos and Docker in Practice with Michael Hausenblas", + "Episodes Uid": "SED9482721052", + "Episodes Audio File": "82e0a7b17871acfaed4c93459a362524.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "9d03d866-f62e-11ea-8c28-2322c929a9b3", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-14", + "Episodes Summary": "


", + "Episodes Title": "UnifyID: Biometric Authentication with John Whaley", + "Episodes Uid": "SED5094039370", + "Episodes Audio File": "d19cfaa20c7e68d6c008b2251560904e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6lc", + "Episodes ID": "eafc94f4-e328-11ea-91a2-87968f752e31", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_13_DataG2MSean.mp3", + "Episodes Pubdate Date": "2020-01-13", + "Episodes Summary": "

Every large company generates large amounts of data. Data engineering is the process of storing, transforming, and leveraging that data. Data infrastructure companies provide tools and platforms for performing data engineering.

The last fifteen years has seen a rise in modern data management companies built in a time of decreasing storage costs, an increased volume of data, and the prevalence of cloud computing. Modern data companies include Hadoop vendors, cloud providers, and a wide variety of individual software companies offering products such as databases, ETL tools, and open source tooling.

The go-to-market strategy for a data infrastructure company requires a deep understanding of the data engineering landscape. A company must build something useful, sell it to customers, and eventually build a replicable strategy.

Sean Knapp is the CEO of Ascend, a company that builds Apache Spark-based data pipelines that connect APIs, data lakes, and data warehouses together to enable data applications. Sean joins the show to talk about the process of building a data infrastructure company, and his lessons building Ascend.

", + "Episodes Title": "Data Infrastructure Go-To-Market with Sean Knapp", + "Episodes Uid": "SED3522908249", + "Episodes Audio File": "be48b1f9508f699816713f5de1ffcfbc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6li", + "Episodes ID": "eaf80ea2-e328-11ea-91a2-97744254522a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_14_RedHatEdge.mp3", + "Episodes Pubdate Date": "2020-01-14", + "Episodes Summary": "

Edge computing is the usage of servers that are geographically close to the client device.

The first common use case for edge computing was CDNs: content-delivery networks. A content delivery network placed media files such as images and videos on multiple servers throughout the world. These are big files, and they take lots of bandwidth to transfer. By placing them at CDNs, the files would be closer to any user around the world.

These early use cases for edge computing were purely about storing large files. But the vast majority of compute still took place at the central application servers.

Over time, users have required faster and faster application experiences. Today, an increasing amount of compute has been moved to the edge, in addition to the existing storage applications. More user data is being cached at the edge to make for quicker transactional processing. Machine learning model training and hosting at the edge makes for a faster, more responsive machine learning feedback loop.

Jaromir Coufal is an engineer with Red Hat. He joins the show to talk about modern applications of edge computing, and how the demand for edge computing is creating a market opportunity for companies that have lots of servers at the edge, such as telecoms. These telecoms can repurpose their widely distributed telecom infrastructure as edge servers that they can sell usage on.

", + "Episodes Title": "Edge Computing Platform with Jaromir Coufal", + "Episodes Uid": "SED6600965867", + "Episodes Audio File": "d0f7c9afbf206e348c204c118bbbdfe4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2c7", + "Episodes ID": "0f2e3ce2-e329-11ea-91a2-efb17f8235bc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/botmemorial_edited.mp3", + "Episodes Pubdate Date": "2016-12-06", + "Episodes Summary": "

When a human passes away, we create a tombstone as a memorial. Friends and family visit a grave to remember the times they had with that person while they were still alive. Memorial bots are another way to celebrate the life of someone who has passed away. A memorial bot is created by taking the messages sent by a deceased person and passing it through a machine learning model in order to make a bot that replicates the deceased person.

Eugenia Kuyda is the CEO of Luka, a company that builds AI products. When her friend Roman Mazurenko suddenly died, she worked with her team to make a bot that replicates his speech patterns. In our interview, we discussed memorial bots, deep learning, and the product Luka is working on–Replika, a personal AI friend for anyone.

", + "Episodes Title": "Bot Memorial with Eugenia Kuyda", + "Episodes Uid": "SED9515445393", + "Episodes Audio File": "3e2ccb0db122daea6ba1fd05d442d16f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ak", + "Episodes ID": "25a5be28-e329-11ea-91a2-6bada92c4b1b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Webtorrent_Edited.mp3", + "Episodes Pubdate Date": "2016-01-15", + "Episodes Summary": "

WebTorrent is a streaming torrent client for the browser that can be used without any additional plugins, extensions, or installations. It is written entirely in JavaScript, and uses WebRTC to handle peer-to-peer communication. There are some limitations to making BitTorrent work over the web using WebRTC, including the inability for a browser-based WebTorrent client or “web peer” to communicate directly with a torrent client.

However, the potential for every browser to contribute to the hosting and streaming of files is unprecedented. Imagine if large content sites like Netflix or YouTube did not have centralized hosting, and instead relied on its users to seed the content to each other using their web clients. This enables not only more efficient networks, but also the ability for each user to contribute to and be part of the content delivery network.

Feross Aboukhadijeh is the creator of WebTorrent. Previously he built PeerCDN, a peer-to-peer content delivery network, which was acquired by Yahoo in 2013.

", + "Episodes Title": "WebTorrent with Feross Aboukhadijeh", + "Episodes Uid": "SED5273292753", + "Episodes Audio File": "e4fac981679b62a11489b61d5f33a6ce.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1en", + "Episodes ID": "23889b92-e329-11ea-91a2-73a9502c20f8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Openshift_Edited.mp3", + "Episodes Pubdate Date": "2016-02-10", + "Episodes Summary": "

You keep hearing about containers, and maybe you have even used Docker in production. Now, it’s time to move beyond Docker. In today’s episode of Software Engineering Daily, Steve Pousty talks about OpenShift, a platform from RedHat that helps engineers leverage the power of containers and the dev ops harmony of microservices.

To hear these buzzwords, you can always listen to Software Engineering Daily. But to see these buzzwords demonstrated in live presentations, the 2016 O’Reilly Fluent Conference is coming up March 8-10 in San Francisco, and you can get a chance to win a free ticket by tweeting at us about your favorite episode of Software Engineering Daily. Include the hashtag #fluentconf and and tag us @software_daily to make sure we can see your tweet.

Steve Pousty is a Developer Advocate (and PaaS Dust Spreader) at Red Hat.

", + "Episodes Title": "Containers and PaaS with Steve Pousty", + "Episodes Uid": "SED7644074157", + "Episodes Audio File": "2dffb6db94677b7513d481504214b9a7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7ag", + "Episodes ID": "e901fe96-e328-11ea-91a2-73440952d0a3", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_06_08_TiltKubernetes.mp3", + "Episodes Pubdate Date": "2020-06-08", + "Episodes Summary": "

Kubernetes continues to mature as a platform for infrastructure management. At this point, many companies have well-developed workflows and deployment patterns for working with applications built on Kubernetes. The complexity of some of these deployments may be daunting, and when a new employee joins a company, that employee needs to get quickly onboarded with the custom dev environment. 

Environment management is not the only issue with Kubernetes development. When a service gets updated, that update needs to be live and usable as fast as possible. When Kubernetes-related errors occur, those problems need to be easily accessible in a UI for triage.

Dan Bentley is the CEO of Windmill Engineering, a company that makes a set of Kubernetes tools called Tilt. Dan joins the show to talk about the workflow for deploying Kubernetes infrastructure and the role of Tilt, the product he has been working on.

", + "Episodes Title": "Tilt: Kubernetes Tooling with Dan Bentley", + "Episodes Uid": "SED7830002726", + "Episodes Audio File": "6f452f672a6d69260fcedab2b7bfc728.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1uy", + "Episodes ID": "1f15abcc-e329-11ea-91a2-2fafd119dcde", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/scaling_emails_Edited.mp3", + "Episodes Pubdate Date": "2016-04-08", + "Episodes Summary": "

When you spend money online, you expect a receipt to come in your email. When you register for a new web site, you need to verify your sign up in your email. These types of emails are called “transactional email” and sending these types of email at scale is a complex engineering task.

J.R. Jasperson is the chief architect at SendGrid, a transactional email platform. On this episode, we discuss how email works–from the basics to the massive scale that SendGrid operates on. We also talk about email spam and fraud in detail.

", + "Episodes Title": "Scaling Email with J.R. Jasperson", + "Episodes Uid": "SED6370641746", + "Episodes Audio File": "11f420f2d7912dd3f9478fcb07c417bc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6jy", + "Episodes ID": "eb18afb8-e328-11ea-91a2-5b92d0e9ba51", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_20_FreeCodeCampQuincy.mp3", + "Episodes Pubdate Date": "2019-12-20", + "Episodes Summary": "

freeCodeCamp was started five years ago with the goal of providing free coding education to anyone on the Internet.

freeCodeCamp has become the best place to begin learning how to write software. There are many other places that a software engineer should visit on their educational journey, but freeCodeCamp is the best place to start, because it is free, and there are no advertisements. 

For most people learning to code, the price of that education is important, because they are learning to code to build a new career. It’s also important that a new programmer learns from an unbiased source of information, because an ad-supported environment will educate the new programmer towards products that they might not need.

freeCodeCamp has not been easy to build. Building freeCodeCamp has required expertise in software engineering, business, media, and community development. The donation-based business model of freeCodeCamp doesn’t collect very much money. Why would somebody build a non-profit when they could spend their time building a highly profitable software company?

Quincy Larson is the founder of freeCodeCamp, and he joins the show for a special episode about his backstory and the journey to building the best place on the Internet for a new programmer to begin.

Support freeCodeCamp

", + "Episodes Title": "freeCodeCamp with Quincy Larson", + "Episodes Uid": "SED4908134854", + "Episodes Audio File": "027be2a13c93c8975a897ab751a1f004.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ab", + "Episodes ID": "25682d88-e329-11ea-91a2-3b587c7b43a1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Datasci_Edited.mp3", + "Episodes Pubdate Date": "2016-01-18", + "Episodes Summary": "

Data science has emerged as an integral discipline alongside software engineering. In this episode, Jeff and Srini discuss the rise of the field, what it means to be a data scientist, and how the field will evolve as more businesses adopt data driven decision making. Srini also explains his thoughts on the essential qualities of a data scientist, and how educating data scientists is a growing challenge in a world that is flooded with “big data”.

Srini Kadamati is a data scientist at Dataquest, where he creates content to help people learn data science.

", + "Episodes Title": "Data Science with Srini Kadamati", + "Episodes Uid": "SED8493113075", + "Episodes Audio File": "b2ef7f3f859c5f72476e98e6079f3d84.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1b2", + "Episodes ID": "24f81584-e329-11ea-91a2-bb87b9e06adc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Riak_Edited.mp3", + "Episodes Pubdate Date": "2016-01-22", + "Episodes Summary": "

Riak is a distributed NoSQL key value data store. It was created by Basho, taking inspiration from the Amazon Dynamo paper. In this episode, Jon and Jeff discuss the benefits and different implementations of non-relational distributed data stores, and why Riak is a compelling option.

Jon Meredith is the chief architect at Basho.

", + "Episodes Title": "Distributed NoSQL Databases with Jon Meredith", + "Episodes Uid": "SED6119895282", + "Episodes Audio File": "8b859fb044bf2e26206a3b8e244e7168.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 280, + "Episodes ID": "132ca63a-e329-11ea-91a2-9fa004a350af", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/continuousdelivery_edited.mp3", + "Episodes Pubdate Date": "2016-10-10", + "Episodes Summary": "

In order to move software updates from the development team to production, companies do a variety of things. Some teams might email files to each other or use FTP or even floppy disks. Most companies today at least use version control systems like Git together with separate servers for development and production. When code is ready to move to production, a build that is on the development server gets copied over to the production servers, and the production servers begin serving real users.

This process is known as deployment, and over the last few decades companies have started deploying more rapidly (even “continuously”), leading to faster iterations and better feedback loops between the software development team and the users of the product. A particularly effective version of this workflow is known as continuous delivery.

In today’s episode, David Rice from ThoughtWorks joins the show to give a short history of continuous delivery, and how continuous delivery actually looks in practice.

", + "Episodes Title": "Continuous Delivery with David Rice", + "Episodes Uid": "SED9044765878", + "Episodes Audio File": "c6e888180de7e345e094a97aed5d8baf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1x4", + "Episodes ID": "1df8652c-e329-11ea-91a2-dbbadb07651e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Kinematic__Full_Edited_2.mp3", + "Episodes Pubdate Date": "2016-04-25", + "Episodes Summary": "

Kubernetes has been a focus of several previous shows on Software Engineering Daily. The architecture and management of our distributed systems have changed, and widespread adoption of containers and container management systems is just beginning.
\nJoseph Jacks from Kismatic joins the show today to give us a perspective on the past, present, and future of container management. He also talks about his company Kismatic, which provides enterprise support for Docker and Kubernetes.

", + "Episodes Title": "Kubernetes, Mesos, and Kismatic with Joseph Jacks", + "Episodes Uid": "SED3702993870", + "Episodes Audio File": "ab4d1c02c1fe50b036f9b699e7a717ca.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6d6", + "Episodes ID": "ebd1cb9c-e328-11ea-91a2-e7f1964fca12", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_29_FBPeterDeng.mp3", + "Episodes Pubdate Date": "2019-10-29", + "Episodes Summary": "

Peter Deng has worked on most of Facebook’s major products: Newsfeed, Instagram, Oculus, and Messenger. These different products have different requirements, but are all part of the same ethos of connecting people through social networks. 

Facebook is a consumer product company that is powered by a strong engineering workforce. The relationship between product managers and engineering are two parts of a three-legged relationship: product, engineering, and design. Every major product within Facebook is built with the teamwork of product, engineering, and design.

After almost ten years at Facebook, Peter joined Uber as the Head of Rider. At Uber, Peter works on a very different platform: a real-world, two-sided marketplace. Every change to the Uber platform has an impact on the economic relationship between riders and drivers. This creates a set of product development constraints that contrast with the social network of Facebook.

Peter joins the show to share how he thinks about product management, and how the core competencies of a business inform product strategy.

", + "Episodes Title": "Facebook Products with Peter Deng", + "Episodes Uid": "SED6307907848", + "Episodes Audio File": "7567d89de9a81bb5b43ccc58c408d59d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6eb", + "Episodes ID": "ebabdfcc-e328-11ea-91a2-2356038d64d8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_08_DroneswithChrisAnderson.mp3", + "Episodes Pubdate Date": "2019-11-08", + "Episodes Summary": "

Drones will deliver food to us. Drones will be able to extinguish fires. Drones will be used to relay Internet signals and make the world more connected. 

These all sound like great ideas, so why aren’t there more drones in the sky today? There are many answers to that question, some of which relate to engineering and some of which are about the regulatory barriers. 

Chris Anderson is the CEO of 3D Robotics, a drone company which he started seven years ago. Before 3DR, Chris worked for many years as a journalist writing about technology and science. He was the editor-in-chief at Wired for 11 years, a writer for The Economist for 7 years, and spent 3 years at both of the leading scientific journals, Nature and Science. Chris also wrote The Long Tail, the influential 2004 book which described a set of emergent Internet trends.

Chris joins the show for a discussion about drones, journalism, and his perspective on modern technology.

", + "Episodes Title": "Drones with Chris Anderson", + "Episodes Uid": "SED2904317236", + "Episodes Audio File": "fb395558bad80729101ed3fd5f23da69.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7k9", + "Episodes ID": "e6439e20-e8c9-11ea-9bc1-8ba75a362527", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_08_26_Wandb.mp3", + "Episodes Pubdate Date": "2020-08-26", + "Episodes Summary": "

CrowdFlower was a company started in 2007 by Lukas Biewald, an entrepreneur and computer scientist. CrowdFlower solved some of the data labeling problems that were not being solved by Amazon Mechanical Turk. A decade after starting CrowdFlower, the company was sold for several hundred million dollars.

Today, data labeling has only grown in volume and scope. But Lukas has moved on to a different part of the machine learning stack: tooling for hyperparameter search and machine learning monitoring.

Lukas Biewald joins the show to talk about the problems he was solving with CrowdFlower, the solutions that he developed as part of that company, and the efforts with his current focus: Weights and Biases, a machine learning tooling company.

", + "Episodes Title": "Machine Learning Labeling and Tooling with Lukas Biewald", + "Episodes Uid": "SED9735737781", + "Episodes Audio File": "6833ce6f2d26c26c8fb69da4a2762d18.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2dq", + "Episodes ID": "0c577858-e329-11ea-91a2-7b05ba349360", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/selfcontained_edited.mp3", + "Episodes Pubdate Date": "2017-01-03", + "Episodes Summary": "

Self-contained systems is an architectural approach that separates the functionality of a system into many independent systems. Each self-contained system is an autonomous web application, and is owned by one team. Communication with other self-contained systems or 3rd party systems is asynchronous where possible.

As Eberhard Wolff explains in this episode, self-contained systems is not the same thing as microservices, but they are not mutually exclusive. Organizations often adopt a mix of architectural ideas, and it is worth understanding these different models so you can decide which of them to apply to your own projects.

", + "Episodes Title": "Self-Contained Systems with Eberhard Wolff", + "Episodes Uid": "SED9825478576", + "Episodes Audio File": "b910c51bdf71aa4bfa8199eaffe4d97a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "79d", + "Episodes ID": "e92a6ebc-e328-11ea-91a2-4f2644464cb2", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_26_EdgeImpulse.mp3", + "Episodes Pubdate Date": "2020-05-26", + "Episodes Summary": "

Devices on the edge are becoming more useful with improvements in the machine learning ecosystem. TensorFlow Lite allows machine learning models to run on microcontrollers and other devices with only kilobytes of memory. Microcontrollers are very low-cost, tiny computational devices. They are cheap, and they are everywhere.

The low-energy embedded systems community and the machine learning community have come together with a collaborative effort called tinyML. tinyML represents the improvements of microcontrollers, lighter weight frameworks, better deployment mechanisms, and greater power efficiency. 

Zach Shelby is the CEO of EdgeImpulse, a company that makes a platform called Edge Impulse Studio. Edge Impulse Studio provides a UI for data collection, training, and device management. As someone creating a platform for edge machine learning usability, Zach was a great person to talk to the state of edge machine learning and his work building a company in the space.

", + "Episodes Title": "Edge Machine Learning with Zach Shelby", + "Episodes Uid": "SED6518144552", + "Episodes Audio File": "3e776528568c19c4a380113338cbc716.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23d", + "Episodes ID": "18bce1a0-e329-11ea-91a2-aff64cc78bdd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Pixar_in_a_Box_Edited.mp3", + "Episodes Pubdate Date": "2016-07-26", + "Episodes Summary": "

Pixar has made some of the most successful movies of all time: Toy Story, WALL-E, Monsters Inc, and many others.

These movies are made with cutting-edge computer animation techniques that Pixar often has to invent in order to tell the story it wants to tell. Pixar has teamed up with Khan Academy to teach anyone who wants to learn the basics of computer animation–Pixar-style.
\nThe collaboration with Khan Academy is called “Pixar in a Box”, and Kitt Hirasaki joins the show to talk about it. Kitt has worked two stints at Pixar, starting in 1996 and again in 2008, and today he works at Khan Academy–so we also get into his experiences at Pixar, and how the software engineering at Pixar works.

", + "Episodes Title": "Pixar in a Box with Kitt Hirasaki", + "Episodes Uid": "SED1813901489", + "Episodes Audio File": "2d386b6dcec05359e7f3140af86ff6dd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6if", + "Episodes ID": "eb2219cc-e328-11ea-91a2-3b50a06d7f15", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_18_RobloxClausMoberg.mp3", + "Episodes Pubdate Date": "2019-12-18", + "Episodes Summary": "

Roblox is a gaming platform with a large ecosystem of players, creators, game designers, and entrepreneurs.

The world of Roblox is a three-dimensional environment where characters and objects interact through a physics engine. Roblox is multiplayer, and users can interact with each other over the Internet. Roblox is not one single game—it is a system where anyone can design and monetize their own games within Roblox.

Over the last 14 years, Roblox has grown to be massively popular. As the product has grown, the software has evolved to meet changes in consumer demands and engineering constraints.

Client devices include mobile phones, desktop computers, and virtual reality. All of these clients must have a consistent experience in graphics and functionality. The backend platform has to support a high volume of concurrent players who are accessing a high volume of content. The networking needs to support multiple players operating in an environment that demands high bandwidth.

Claus Moberg is a vice president of engineering at Roblox. He joins the show to discuss the engineering of Roblox and the future of gaming.

", + "Episodes Title": "Roblox Engineering with Claus Moberg", + "Episodes Uid": "SED9315075580", + "Episodes Audio File": "71f38637bc0bb311eeefefd357e5678e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 168, + "Episodes ID": "272442c4-e329-11ea-91a2-d3e531707f5e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Vue_Edited.mp3", + "Episodes Pubdate Date": "2015-12-29", + "Episodes Summary": "

Vue.js is a lightweight front-end JavaScript framework that makes it simple to begin prototyping and building web interfaces. Vue.js provides a flexible API for MVVM data bindings, and can serve as an alternative to other front-end frameworks like Angular and React.

Evan You is the creator of Vue and a core developer at Meteor.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "VueJS with Evan You", + "Episodes Uid": "SED1794266013", + "Episodes Audio File": "20e7bb668ae7824339c90f5a953767f3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "29e", + "Episodes ID": "11ed620a-e329-11ea-91a2-7fbd637cecdd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/bobhofman_edited.mp3", + "Episodes Pubdate Date": "2016-11-01", + "Episodes Summary": "

Online advertising is heavily affected by a set of delusions and fraudulent practices that few people in the adtech industry have an interest in stopping. This is the curious, perverse nature of the world of online media. Some of the online advertising we see fulfills its job, when an ad successfully conveys a meaningful message from a marketer to a consumer.

But there are reasons to be extremely skeptical of the way that online advertising works. In this episode, and several more to come, Software Engineering Daily will be diving deep into the adtech business to understand the bot fraud and mass psychosis that bolsters our tech media giants.

Bob Hoffman is the author of The Ad Contrarian, a long-running blog about advertising. After selling the advertising agency he was running, he left the industry. In today’s episode, Bob discusses his experience in the ad industry, and the delusions he saw when he was working in it.

", + "Episodes Title": "Ad Industry with Bob Hoffman", + "Episodes Uid": "SED1533450986", + "Episodes Audio File": "ddba3fd8764f0a59f023721b14c7fbcc.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1w9", + "Episodes ID": "1e351d8c-e329-11ea-91a2-af320e3a6ce9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Borg_Edited_2.mp3", + "Episodes Pubdate Date": "2016-04-20", + "Episodes Summary": "


\nKubernetes is an open source system for automating deployment, operations, and scaling of containerized applications. Google developed Kubernetes after fifteen years of running containers in production.
\nBrendan Burns is a founder of the Kubernetes project, and he joins us to talk about the lessons learned as Google has built containerized applications to distribute across its massive infrastructure. We talk about Docker, Borg, Kubernetes, and other distributed systems technologies.

Applications crash, and engineers need to be able to quickly find the root cause of a crash. Apps have become distributed, and debugging workflows have changed. Developers need better tools to identify and troubleshoot problems with their apps.

", + "Episodes Title": "Google’s Container Management with Brendan Burns", + "Episodes Uid": "SED7756314923", + "Episodes Audio File": "dc7ce1f9467f02582b3c71461d2713bb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6r1", + "Episodes ID": "ea9233a2-e328-11ea-91a2-1b04b5fd7b09", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_12_FlinkandBeam.mp3", + "Episodes Pubdate Date": "2020-02-12", + "Episodes Summary": "

Distributed stream processing systems are used to read large volumes of data and perform operations across those data streams. 

These stream processing systems often build off of the MapReduce algorithm for collecting and aggregating large volumes of data, but instead of processing a calculation over a single large batch of data, they process data on an ongoing basis. There are so many different stream processing system for this same use case–Storm, Spark, Flink, Heron, and many others. 

Why is that? When there seems to be much more consolidation around the Hadoop MapReduce batch processing technology, why are there so many stream processing systems?

One explanation is that aggregating the results of a continuous stream of data is a process that very much depends on time. At any given point in time, you can take a snapshot of the stream of data, and any calculation based on that data is going to be out of date by the time that your calculation is finished. There is a latency between when you start calculating something, and when you finish calculating it.

There are other design decisions for a distributed stream processing system. What data do you keep in memory? What do you keep on disk? How often do you snapshot your data to disk? What is the method for fault tolerance? What are the APIs for consuming and processing this data?

Maximilian Michels has worked on the Apache Flink and Apache BEAM stream processing systems, and currently works on data infrastructure at Lyft. Max joins the show to discuss the tradeoffs of different stream processing systems and his experiences in the world of data processing.

You can find all of our past episodes about data infrastructure by going to SoftwareDaily.com and searching for the technologies or companies mentioned. And if there is a subject that you want to hear covered, feel free to leave a comment on the episode, or send us a tweet @software_daily.

", + "Episodes Title": "Flink and BEAM Stream Processing with Maximilian Michels", + "Episodes Uid": "SED1393979012", + "Episodes Audio File": "9f2b3c53ee7e317338ef7ff102f05dfb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6mr", + "Episodes ID": "eae12912-e328-11ea-91a2-07c925c8c51e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_21_WebflowBryantChou.mp3", + "Episodes Pubdate Date": "2020-01-21", + "Episodes Summary": "

Webflow is a visual programming tool used by designers, developers, and other technical users. Webflow is a leader in the “low code” or “no code” category of software tools that has become prominent in the last few years. 

Webflow has been years in the making. In a previous show with Webflow CEO Vlad Magdalin, he told the story of being heads down on Webflow, steadily working through the engineering problems that stood between him and his vision of a visual programming environment.

In the early days, it was unclear who would even want to use Webflow. A critic of Webflow might have said that Webflow was too high level for developers, and too technical for designers. But Webflow caters to a large subset of developers and designers who want the kind of low code experience that Webflow provides. The product has also helped define a new category of knowledge worker: the “visual programmer.”

Bryant Chou is a co-founder of Webflow and was the CTO in the early days. He joins the show to discuss the engineering problems that the company has had to work through, and his perspective on how Webflow fits into the software market going forward.

", + "Episodes Title": "Webflow Engineering with Bryant Chou", + "Episodes Uid": "SED7253321877", + "Episodes Audio File": "56c75973cb749003eefead2faaf837fd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6mz", + "Episodes ID": "ead791ea-e328-11ea-91a2-6ba67122c9ac", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_23_KubernetesatLyft.mp3", + "Episodes Pubdate Date": "2020-01-23", + "Episodes Summary": "

The ridesharing infrastructure of Lyft has a high volume of traffic that is mostly handled by servers on AWS. When Vicki Cheung joined Lyft in 2018, the company was managing containers with an internally built container scheduler. One of her primary goals at the company was to move Lyft to Kubernetes.

In today’s episode, Vicki gives an overview of Lyft infrastructure and the core engineering problems within the company. One subject she touched on was the network communications between the user on a mobile phone and the cloud backend. This was a topic we explored in detail on a previous episode about Envoy Mobile with Matt Klein.

Vicki also discussed the broader Kubernetes ecosystem, as well as her time at OpenAI, where she managed infrastructure deployments for scheduling large machine learning jobs.

", + "Episodes Title": "Lyft Kubernetes with Vicki Cheung", + "Episodes Uid": "SED3394440048", + "Episodes Audio File": "8be077f487dd8674b63b974d0cb881e9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1pn", + "Episodes ID": "2104bc70-e329-11ea-91a2-bf8df848fffc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Cassandra_Edited.mp3", + "Episodes Pubdate Date": "2016-03-11", + "Episodes Summary": "

Apache Cassandra can serve as both the real-time data store for online transactional applications, as well as the read-intensive database for data warehousing operations. In order to combine these two use cases into a single database, Apache Cassandra required lots of innovation.

In today’s episode of Software Engineering Daily, we discuss the internals of Cassandra. Tim Berglund takes us through how Cassandra performs reads and writes, how Cassandra offers tunable consistency, and what inspirations Cassandra took from the Amazon Dynamo paper as well as the Google BigTable paper. Tim will also be presenting at Strata + Hadoop World in San Jose. We’re partnering with O’Reilly to support this conference – if you want to go to Strata, you can save 20% off a ticket with our code PCSED.

", + "Episodes Title": "Cassandra with Tim Berglund", + "Episodes Uid": "SED9234120824", + "Episodes Audio File": "5a6c97ad9b6eeff825f3261fec39a648.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "9963910a-fbbb-11ea-a515-eb0468342dc3", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-21", + "Episodes Summary": "


", + "Episodes Title": "TornadoVM: Accelerating Java with GPUs with Juan Fumero", + "Episodes Uid": "SED3751644090", + "Episodes Audio File": "cfb6820ec4b7f7899d52aa4a6683e879.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4xg", + "Episodes ID": "f092f980-e328-11ea-91a2-732a39d24fc4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_13_Platform9.mp3", + "Episodes Pubdate Date": "2018-11-13", + "Episodes Summary": "

Serverless computing abstracts away the idea of a server node. Serverless lets programmers treat compute resources as high-level, reliable APIs, rather than unreliable, low-level compute nodes that might fail.

Serverless dramatically improves the efficiency of programmers. Instead of thinking of a database as a set of servers that need to be sharded and replicated, the programmer can think of a database as a place to read and write data. Instead of modeling an application as a large monolith running on an application server in a container or a VM, the programmer can think of their application as a decoupled set of functions.

Serverless computing is a natural evolution of software engineering in a world with cloud providers. The first version of FaaS came out of AWS with their Lambda service, which allows users to run functions in the cloud. Those functions are scheduled onto a physical server somewhere in an Amazon data center. They are executed, and they return the result.

With AWS Lambda, programmers got a new abstraction to model their applications with. But it requires the use of a closed-source API. Lambda is not open source, and this makes some developers reluctant to integrate with it too tightly.

Fission is an open source framework for serverless functions built on Kubernetes. Fission allows developers to deploy functions-as-a-service without being locked in to any specific cloud provider.

Soam Vasani is the creator of Fission and an engineer at Platform9. In a previous episode, Soam talked about the architecture for Fission and the design choices for solving the cold start and scheduling problems.

Soam joins the show today to discuss how serverless applications have evolved since last spoke more than a year ago. He also talks about how Fission itself has evolved, and the features that an open source serverless platform needs to have in order to compete with a fully developed cloud provider. Full disclosure: Platform9 is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Fission: Serverless on Kubernetes with Soam Vasani", + "Episodes Uid": "SED7306528235", + "Episodes Audio File": "", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1vc", + "Episodes ID": "1ed4650e-e329-11ea-91a2-8f30f5aef61c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/frontend_Edited.mp3", + "Episodes Pubdate Date": "2016-04-11", + "Episodes Summary": "

Frontend web development was simpler in the past–CSS, HTML, and JavaScript were all you needed to know. Today, we have mobile web, React, Angular, PHP, JQuery, and so much more.

Marc Grabanski focuses on what he believes is timeless–pure JavaScript. Marc is the founder of Frontend Masters, a training site for developers who want to build quality web interfaces. He joins us today to discuss the shifting nature of front end development.

", + "Episodes Title": "JavaScript and Frontend Development with Marc Grabanski", + "Episodes Uid": "SED4978282405", + "Episodes Audio File": "8a177eefd3c9f954fcdba2f92526ede6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1s7", + "Episodes ID": "1f6df610-e329-11ea-91a2-1b80e6747e92", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/poker_and_software_engineering.mp3", + "Episodes Pubdate Date": "2016-04-03", + "Episodes Summary": "

The last editorial we did was 10 Philosophies for Engineers. Listeners enjoyed that episode, so we decided to do another.

10 Philosophies was a collection of beliefs I have about the software engineering industry, and how we can find fulfillment in our work as engineers. The philosophies that I discussed were rooted in my experiences working as a computer science student and as an engineer at several different companies.

Before writing any lines of code, I played poker competitively for five years, from the age of 15-20. This was a formative experience. Playing poker changed my perspective on money, risk, and statistics.

It has been 7 years since I stopped playing poker full time, but the lessons of the game are still with me.

In this editorial, I will discuss some beliefs I have that relate to both poker and software engineering.

As with the 10 Philosophies episode, these beliefs my own opinions. If you disagree with them, I would love to know why. At Software Engineering Daily we actually want to know any thoughts you have on our content.

We make content for our listeners and our readers. Please tell us how we can improve by emailing us, or by filling out the listener survey.

As a poker player becomes a software engineer, certain trends about human-computer interaction become apparent:

This post explores each of these trends, explaining why these trends are important to poker players, software engineers, and everyone else.

Automated Games

In 2008, poker was the perfect sport for human-computer symbiosis. What Tyler Cowen said about freestyle chess also applied to poker:

In poker, a human with a statistical “heads-up” display can make decisions that are more mathematically justified than a human without such a tool.

Heads-up displays create the poker version of “human-plus-machine teams”.

One thesis of Average is Over is that a human will only be employable in the future by finding a career where human reasoning provides defensible value to the problem solving process of a computer.

If the human’s responsibilities are not defensible, the human will beobviated.

In a subsequent blog post, Cowen addresses the “flip” that can occur when a computational problem no longer requires human assistance:

Poker players have been increasingly defeated by machines for the past 10 years. It is no surprise that Google’s AlphaGo has defeated human champion Lee Sedol.

If Google decided to beat humans at poker, it would be a trivial exercise for the researchers.

Poker seems different than Go or Chess, since there is nondeterminism. You start with two cards, but you don’t know how the board will develop. It would seem that fate is in control, unlike Go and Chess, which have no random elements.

With just 4 suits and 13 ranks, a poker game has a trivial branching factor. The nondeterminism is so minimal for a computer to plan around that it is effectively deterministic.

Imagine if AlphaGo had to learn to play a version of Go with the following rule: at the beginning of each turn, flip a coin. If you lose the flip, you don’t get to move. Adjusting to this rule would be trivial. That is the magnitude of nondeterminism within poker.

Poker, Chess, and Go have small decision spaces. The rules never change, the game pieces never change, there is minimal nondeterminism.

A computer can assess a hand of poker as it would a hidden Markov model, but it will take work on par with the AlphaGo team for a computer to be trained to build a model accurately.

The job of a professional poker player has been a bad long-term choice for a human to pursue for more than a decade, because it is vulnerable to automation.

Games like Go, Poker, and Chess can be automated with machine learning techniques we understand today. The rules, game piece schema, and objectives are easy to define, so these games are ripe for supervised learningand reinforcement learning.

Yann LeCun protested against the hype around the AlphaGo victory:

Poker is vulnerable to the same supervised learning and reinforcement learning techniques that allowed AlphaGo to beat Lee Sedol in Go.

Supervised learning is the machine learning task of inferring a function from labeled training data. Billions of hand histories exist for a poker bot to train on. These hand histories are short and well-schematized, perfect for consumption by an automaton.

Reinforcement learning is learning by interacting with an environment. Poker bots can test and parallelize their strategies across the thousands of free or cheap poker games on the internet. The reward signal of a strategy can be defined as profit over a given time horizon.

Today, the surviving human professionals cannibalize each other. Before long, even the best of these players will be losing their money to bots.

Games that cannot be easily solved with simple supervised learning and reinforcement learning will not be automated in the near future. Examples include Magic: the Gathering, Sim City, Minecraft, and Dungeons and Dragons.

Features of these games include:

Rules, success, and failure are easy to define in Go, Chess, and Poker.

In contrast, it is difficult to explain what makes an ideal Minecraft player. Different Minecraft players have different goals and win conditions. We have no way to supervise a computer to succeed at Minecraft, or to reward a computer for its desirable Minecraft behavior.

Poker has 52 game piece types, Chess has 6, and Go has 1. Magic: the Gathering has 16,000+ unique cards. We don’t know how to teach a computer to understand the complex strategic relationships among these 16,000 different card types.

Dungeons and Dragons is cooperative, positive sum, highly random, and oriented around subjective player goals. A computer won’t rival the creative, utilitarian humanism of a talented dungeon master any time soon, because we don’t have a good way to codify the traits of a successful game of Dungeons and Dragons.

As humans, these are the games we should be studying and celebrating.

Go, Chess, and Poker were excellent pastimes before the renaissance of games we have had in the last 30 years. Today, there are better games.

AlphaGo proves that Go is just another routine that can be automated, like fast food preparation or truck driving.

Rather than spending our time on Chess, Go, or Poker, human time is better spent playing games that mirror activities which a computer has trouble with.

Choosing a career as a professional poker player today is like choosing to be an Uber driver or an Amazon warehouse worker: you are waiting to be automated away.

Madness of Crowds

In both poker and software, market participants confuse technical analysiswith fundamental analysis.

Pure technical analysts believe dogmatically in the wisdom of the crowds.

Technical analysts believe there are no secrets, and that all human knowledge about the future is factored into the crowd’s evaluation of the present.

Reasoning about markets using first principles can lead to decisions that differ from the wisdom of the crowds. This is a form of fundamental analysis.

In 2003, an accountant turned amateur poker player named Chris Moneymaker won the World Series of Poker. This coincided with ESPN’s increase in video coverage of the event. People started going to restaurants to watch poker like it was the Super Bowl.

As poker became popular across the world, many unskilled players began playing the game.

In 2004, any computer-savvy teenager could learn to play poker and take money from the numerous unskilled Americans who were trying to become the next Chris Moneymaker.

There was a wealth of information about how to win at poker online, and it didn’t require much effort to study enough of that information to be successful.

For teenagers who were good at online games, it was a gold rush. Teenagers who had skills from games like StarCraft and Magic Online quickly learned poker and began obliterating the unskilled amateurs.

In 2006 the online poker bubble sprung a leak with the passage of the UIGEA. The Unlawful Internet Gambling Enforcement Act of 2006 made it difficult for amateur players to fund their online poker accounts with credit cards.

In 2008 the global economy collapsed, further reducing the number of casual gamblers on the Internet.

In 2011 Black Friday occurred and it was discovered that Full Tilt Poker was a Ponzi scheme.

Since 2006, online poker has gotten increasingly difficult, and an ever growing number of poker players have complained about the macro environment of poker.

Google Trends says that poker popularity has dropped by 80% following the passage of UIGEA in late 2006.

Since 2006, poker players have been saying: “there are no more weak amateurs. We are all fighting each other, and because we all have the same strategies, we are essentially flipping coins against each other. Poker has become a game of complete variance.”

None of this matters to Dan Cates, Mike McDonald, and Patrik Antonius. Their strategy is sufficiently better than their opposition that they have afundamental opportunity. They have continued to win despite a steep increase in competition.

Average poker players who are not innovative nor resilient viewed the events of 2006–2011 as fundamental threats to their viability as professional poker players, when in fact these problems were technical in nature.

The details of the market changed, but the fundamental opportunity remained: the best players still have enough of an edge to make a great living playing poker.

When investors and entrepreneurs talk about a “bubble” in Silicon Valley, they are talking about a technical bubble. Not a fundamental bubble.

Cheap cloud computing, mobile phones, emerging markets of China and India, social networks, Docker, Bitcoin, supply chain economics, drones, fintech, virtual reality: these are fundamental opportunities with huge growth potential.

When investors and entrepreneurs talk about how “Winter Is Coming”, what are the cited underpinnings of their panic?

Technical analysis that has little to do with the viability of growth-driving breakthrough technology.

Institutional investors pulling out of private markets? China being a house of cards? Oil? Greece? Technical chart patterns of 1999 showing a run-up that mirrors modern private markets? Food delivery startups being propped up by other startups?

There is no surer sign of the madness of crowds than when investors look to each other rather than fundamentals as they try to divine the true nature of private markets.

Investors who claim to pride themselves on long-term thinking often forget the technological fundamentals that determine long-term viability of companies.

From 2006 to 2011, thousands of professional poker players quit the game, convinced that a certain popular narrative was true: poker had finally become a game of luck.

Weak poker players quit as the bubble popped because they were convinced that poker had become so competitive that it was impossible to have an effective, differentiated strategy.

Poker players who have faith in their own creativity continue to make a living through hard work and study.

In the near future, the antiportfolios of herd-mentality technology investors will swell at unprecedented rates as investors mistakenly look to each other for guidance, rather than looking at the fundamental opportunities afforded by our current technological boom.

Emotional Labor

In 2004 and 2005, college students and well-educated yuppies started playing poker because it was a low-risk, easy way to make money. Wealthy, amateur American poker players were losing money to these college students and yuppies.

There was a huge difference in skill between these two classes of players.

The college students and yuppies read books about statistics, psychology, and complex poker strategy. The wealthy, amateur Americans watched poker on TV and tried to copy what they saw professionals doing on the screen.

For the well-educated college students and yuppies, the only requirement for succeeding at high-stakes poker was patience.

Patience was important because the wealthy, amateur Americans played so poorly that a college student could sit around waiting for opportunities to get money into the pot with a 10:1 advantage.

From 2006 to 2011, legislative and economic circumstances pushed many of the amateur American players out of the game. As the wealthy amateurs disappeared from poker, the high-stakes field became 95% professionals.

In 2005, an average 6-handed online poker table contained 3 professionals and 3 amateurs. In 2006, an average table contained 4 professionals, 1 skilled amateur, and 1 weak amateur. By 2008, most tables were entirely filled with professionals and skilled amateurs.

Weak opponents were nowhere to be found.

In this new world of almost entirely professional poker players, emotional resilience was more important than patience.

Professional players could no longer wait for a clear 10:1 or 5:1 advantage over their opponents. The timid college students and yuppies who maintained a patient, uncreative strategy started to lose money.

Chaotic, hyperaggressive players began to force games in a direction with increased variance, making their opponents call into question their presumed risk-of-ruin. The most extreme example of this was Viktor Blom, a high-stakes player whose willingness to go broke seemed to exceed his fear, leading to a style where he would frequently overbet the pot.

A professional playing against Viktor Blom knew that more money would belost or won in a short time frame than against anyone else.

For Viktor Blom, the primary cost of using this strategy was that emotional control is harder to maintain when you are winning and losing millions of dollars on a more frequent basis than your opponents.

The tradeoff was worth it. Viktor Blom’s brilliant strategy gave him both amathematical advantage and a reputation advantage.

Why is this relevant to software engineering?

Viktor Blom gained massive competitive advantage by committing emotional labor.

He deliberately played poker in a way that was uncomfortable to everyone at the table, because he judged himself as more capable of dealing with that discomfort than everyone else.

Most software engineers avoid emotional labor.

When software engineers choose to work at a large corporation because it seems luxurious and safe, they are making a mistake. There has never been a better time for engineers to take extreme risks with their careers.

Software engineers are incredibly privileged. Our 9–5 jobs are enjoyable and creative, and many of us have significant free time to do whatever we want. During their free time, software engineers should stretch themselves and exert emotional labor, and see what they are capable of.

In 2005, professional poker players had the option to live a carefree lifestyle. We assumed the gold rush of online poker would never end. Many of us acted irresponsibly with money, as if we would be able to make $30,000 a month for the rest of our lives.

When the poker economy collapsed, many professional poker players’ lives collapsed with it. We had gotten accustomed to The Good Life, but we hadn’t worked hard enough to capitalize fully on the opportunity at hand.

Poker players who worked hard and worked smart during the 2003–2007 boom years were able to survive the bust.

Most poker players did not work hard and smart during the boom.

Most poker players did not practice emotional labor in 2005, when the game was easy. When poker became difficult in 2008, these players were fragile. Most professional poker players were unable to adapt to the newly competitive landscape.

In contrast, Viktor Blom got used to high-risk activity around 2005, shortly after he started to play poker:

Viktor Blom went broke twice as a teenager.

Going broke is not always virtuous. For some poker players, being broke is an addiction. They will make a career out of the manic-depressive cycle of building huge piles of money, only to lose it all.

Viktor Blom became antifragile from his early experiences going broke.

This was long before his winning streak in 2009. When the poker economy collapsed, it didn’t severely affect Viktor Blom because he had been forcefully challenging himself for years before.

In the early days of his career, Viktor relentlessly took risks. The strength of the 2005 poker economy allowed him to rebuild his bankroll each time he went broke.

Software engineers today should be acting like Viktor Blom in 2005.

In 2005, Viktor could lose his entire bankroll playing high stakes, it was easy to rebuild at mid-stakes games. By increasing short-term risk of ruin, he decreased long-term risk of ruin.

In 2016, a software engineer can quit a corporate job and build side projects for 6 months. If none of the side projects turns into a marketable product, that engineer can always go back to the corporation, and can probably ask for a higher salary thanks to the new skills learned from working on those side projects.

Risk taking is an act of emotional labor.

Software engineers can build a product, start a business, write an algorithm, launch a rocket, or program a self-driving car. All of these activities require risk. But many software engineers spend their spare time doing activities with very low risk.

If you commit to being a software engineer who is willing to take risks and commit to emotional labor, you can easily stand out from others.

Build Your Own Ship

I spent my late teenage years playing poker and didn’t write a line of code until my early twenties. Most of the successful engineers I know were coding during their teens.

In order to catch up, I have had to leverage the skills I learned playing poker.

Many new engineers today are faced with the same problem.

You are learning to code as a second career, and it can feel very difficult because it feels like you are throwing away everything from the past and starting from scratch.

Whether you are trained as a barista, a salesperson, or a biologist, you must find skills from your past that you can carry into your career as a software engineer.

A barista is great at sequencing operations that are less trivial than they seem. A salesperson understands how to work with clients and cater to their needs in high-stakes projects. A biologist understands abstractions, and how to think about individual parts of a system in isolation.

Being an outsider is a disadvantage at first, but over time it has tremendous value.

Every job you have had in the past has transferrable skills that can be applied to software engineering. Identifying the advantages you have developed from your past experiences can help you feel more confident.

When you start out as a software engineer, many developers will tell you what to do and how you should act.

These people say: Learn JavaScript. Go to a coding boot camp. Write tests for all your code. Learn to make mobile apps. Use StackOverflow. Learn functional programming. Become a master of the command line.

Every person learns software engineering differently.

Software engineering is an art. To succeed as artists, we have to decide what tools and methodologies we want to use. We have to decide for ourselves.

Poker is also an art. There is no objectively “best” way to play poker. Poker players develop their art form through years of subjective experience.

Haseeb Qureshi described this in “Poker as Shipbuilding”, a section from his masterpiece The Philosophy of Poker:

As a poker player, I failed because I copied what I saw other people doing without understanding the reasoning behind it. I did not build my own ship as a poker player.

If your strategy is to copy others, you cannot differentiate yourself from the global talent pool. You cannot differentiate yourself from the machines that are getting smarter every day.

As a software engineer, I try not to make the mistake of blindly copying what is fashionable. A decade ago, I lost most of my money because I was simply following what others were doing.

It is useful to have such a history of pain associated with copying others.

For most people, blindly copying others alleviates pain. When I feel like I am copying others without understanding why, my gut response is to be ashamed and scared of own tendency to replicate.

If you don’t copy the behavior of other engineers, your manager cannot treat you as a highly predictable commodity. You can’t be spun up and assigned to a task like an EC2 cluster.

If you aren’t a highly predictable commodity, you will probably be fired or promoted.

Unfortunately, most companies are not set up to support or encourage entrepreneurial behavior.

Many software engineers end up stuck in jobs that make them unhappy because they simply take orders and do not think through things themselves, considering all their options, and seeing the bigger picture.

Software engineers need to build their own ships.

If your strategy as a software engineer is to only copy what you have already seen, you will follow people into old technologies. You will start companies in crowded markets. You will find yourself surrounded by other people who are afraid to create their own strategies, technologies, and products.

If you build your own ship, the world is full of opportunity.

", + "Episodes Title": "Poker and Software Engineering", + "Episodes Uid": "SED9957668314", + "Episodes Audio File": "d8dd37f6209dc200ea723c2a765f8c27.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 282, + "Episodes ID": "13032bf2-e329-11ea-91a2-db8d6fe72b20", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/monitoring_theo_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-10-11", + "Episodes Summary": "

Building a monitoring system is a complex distributed systems problem. Events are produced from different points in an application and must be aggregated in order to form metrics. These events are often ingested by a time series database, which forms the backbone of our monitoring system.

Theo Schlossnagle is the CEO of Circonus, where he has been working on architecting the company’s monitoring software for six years. In this episode, we talk about how to build a monitoring system and the requirements for the underlying time-series database, as well as what monitoring even is.

", + "Episodes Title": "Monitoring Architecture with Theo Schlossnagle", + "Episodes Uid": "SED2679287048", + "Episodes Audio File": "008c9e69a286399f2cc469e9d71a81dd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5et", + "Episodes ID": "ef29b9e4-e328-11ea-91a2-ff0abdad4858", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/findcollabs.mp3", + "Episodes Pubdate Date": "2019-03-03", + "Episodes Summary": "

Collaboration on the Internet creates innovation. New inventions, new art, and new products–built by people working together on the Internet.

FindCollabs is a product we have been working on to enable people to find and collaborate with each other. If you want to try it out, you can go to FindCollabs.com.

FindCollabs is for finding people to create your projects with, and getting those projects built. Whether you are a programmer, a writer, a musician, a game designer, an actor, a videographer, or a project manager–you can find people to collaborate with.

I love to work on so many different types of projects, and I love to collaborate with other people. For me, the best way that I learn new skills is by building things. I like to write music, create software, make podcasts, and build businesses. I like to create all the time.

For big projects, it’s easier to build your project with a team. Finding team members can be very hard. I value other people who are creative and reliable.

FindCollabs lets you find and invite people to your projects, so that you can put together a team to build your project.

FindCollabs also has a reputation system.

When you work on a project, your collaborators rate you. As you make contributions to projects, you show the FindCollabs community that you are reliable and productive–and other people will want to work with you because of that.

The only way to build huge, ambitious projects as a team is for people to trust each other. If you are unreliable, people will not want to work with you.

When you join a project on FindCollabs, you are committing to doing work that will add value to that project.

If you like to build projects and be creative, you might like FindCollabs. To get started, you can go to FindCollabs.com, log in, and post a project. Or join someone else’s project.

If you are ever confused about anything, you can always send me an email.

We are sponsoring a series of hackathons on FindCollabs.

These hackathons are for anyone with a creative project–whether you want to make a music video, a virtual reality game, an acoustic guitar song, a cryptocurrency whitepaper, a mobile app, a commercial–anything creative.

Our first hackathon starts today, March 3rd 2019, and ends at 11:59 PM PST on Saturday March 16th. On March 17 2019 we will announce the winners of the first hackathon, and send them emails. We will also announce the details of the second hackathon.

Prizes

In the first hackathon, the prizes are not very big. But they will get bigger over time. If you like the idea of FindCollabs, it might benefit you to get involved now, so that you can build your reputation and find better people to work with in the future.

1st place: $500 divided evenly among the winning team; SE Daily hoodies for each member of the team

2nd place: SE Daily hoodies for each member of the team

Most valuable feedback on the product: SE Daily Towel

Most helpful community member award: SE Daily Old School Bucket Hat

The FindCollabs hackathons will be judged by a panel of investors, entrepreneurs, podcasters, artists, and technologists. We will announce the judges of the first hackathon in the next few days.

These judges will be voting based on which projects they like the most.

Every project on the FindCollabs site before 11:59 PM PST on Saturday March 16th will be entered to win the contest.

To find our detailed terms and conditions, go to findcollabs.com/terms.

Thanks for taking the time to read through this post. If you get a chance, check out FindCollabs and feel free to send me feedback. I’d love to know what you think, and any suggestions you have.

", + "Episodes Title": "FindCollabs", + "Episodes Uid": "SED4594155587", + "Episodes Audio File": "9da35fa07cb13899958a379600452d9c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3zr", + "Episodes ID": "f29c5140-e328-11ea-91a2-5b7ca9f1b43f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_18_Dremio.mp3", + "Episodes Pubdate Date": "2018-06-18", + "Episodes Summary": "

Twenty years ago, all of the data in an organization could fit inside of relational databases.

Imagine a company like Proctor and Gamble. P&G is a consumer packaged goods company with hundreds of business sectors–shaving products, toothpaste, shampoo, laundry detergent.

Twenty years ago, if the chief financial officer of P&G wanted to answer a question about the revenue projections within the enterprise, that CFO would ask a VP to find the answer. The VP would contact the business analysts in all the different departments within Procter and Gamble, and those business analysts would all work with database administrators to answer questions for their business sector. In that world, it might have taken weeks or months for the CFO to get the answer about revenue projections.

Today, data engineering has improved dramatically. Data sets within an enterprise are updated more rapidly. The tooling has advanced thanks to the Hadoop project leading to a wide range of open source projects that feed into one another.

But data problems across an enterprise still exist. Business analysts, data scientists, and data engineers struggle to communicate with each other. The CFO still can’t get a question about revenue projections answered instantly. Instead of instant answers, we live in a world of friction, batch processing, and monthly reports.

And this is not just true of old enterprises like P&G. It is true of newer startups like Uber, Airbnb, and Netflix. It seems that no amount of engineers and financial windfall can completely cure the frictions of the modern data platform.

Tomer Shiran started Dremio to address the long-lived problems of data management, data access, and data governance within an enterprise. Dremio connects databases, storage systems, and business intelligence tools together, and uses intelligent caching to make commonly used queries within an organization more readily accessible.

Dremio is an ambitious project that spent several years in stealth before launching. In today’s episode, Tomer gives a history of data engineering, and provides his perspective on how the data problems within an organization can be diminished. Full disclosure: Dremio is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Dremio Data Engineering with Tomer Shiran", + "Episodes Uid": "SED3807409934", + "Episodes Audio File": "d013c965b1d03ee1948f680358dfa203.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2kk", + "Episodes ID": "015da576-e329-11ea-91a2-1f8bcebe32da", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/complacency_edited.mp3", + "Episodes Pubdate Date": "2017-04-07", + "Episodes Summary": "

Engineers in Silicon Valley see a world of constant progress. Our work is creative and intellectually challenging. We are building the future and getting compensated quite well for it.

But what if we are actually achieving far less than what is possible? What if, after so many years of high margins, gourmet lunch, and self-flattery, we have lowered our standards for innovation? And if Silicon Valley has been lulled into complacency, what does that say about the rest of the United States?

American exceptionalism has faltered and complacency has risen in its wake.

Today’s guest Tyler Cowen is an economist and author. His new book The Complacent Class is the final book in a trilogy that describes a decline of American output and a decline in American mindset.

Complacent America has lost its ability to assess risk. Children are prevented from playing tag for risk of injury. College students protest against speakers who might present challenging ideas. The number of Americans under 30 who own a business has fallen by 65% since the 1980’s–millennials are too busy going to business school to start businesses.

In his books, Tyler weaves together history, philosophy, and contemporary culture. He presents hard data about many different fields, and theorizes about how the trends in those fields relate to each other.

He also has a podcast, Conversations with Tyler, and in this episode I tried to mirror his interview style. If you like this episode, you should check out his show–he has interviewed people like Ezra Klein, Peter Thiel, and Kareem Abdul-Jabbar.

", + "Episodes Title": "Complacency with Tyler Cowen", + "Episodes Uid": "SED7998826135", + "Episodes Audio File": "2c2c6608613bb38e3ec6164ff660cd29.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3dn", + "Episodes ID": "f4d1dc50-e328-11ea-91a2-97e211168dcb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_13_GravityOfKubernetes.mp3", + "Episodes Pubdate Date": "2018-01-13", + "Episodes Summary": "

Kubernetes has become the standard way of deploying new distributed applications.

Most new internet businesses started in the foreseeable future will leverage Kubernetes (whether they realize it or not). Many old applications are migrating to Kubernetes too.

Before Kubernetes, there was no standardization around a specific distributed systems platform. Just like Linux became the standard server-side operating system for a single node, Kubernetes has become the standard way to orchestrate all of the nodes in your application.

With Kubernetes, distributed systems tools can have network effects. Every time someone builds a new tool for Kubernetes, it makes all the other tools better. And it further cements Kubernetes as the standard.

Google, Microsoft, Amazon, and IBM each have a Kubernetes-as-a-service offering, making it easier to shift infrastructure between the major cloud providers. We are likely to see Digital Ocean, Heroku, and longer tail cloud providers offer a managed, hosted Kubernetes eventually.

In this editorial, I explore the following questions:

Standardized software platforms are both good and bad.

Standards allow developers to have expectations around how their software will run. If a developer builds something for a standardized platform, they can make smart estimations about the total addressable market for that piece of software.

If you write a program in JavaScript, you know that it will run in everyone’s browser. If you create a game for iOS, you know that everyone with an iPhone will be able to download it. If you build a tool for profiling garbage collection in .NET, you know that there is a large community of Windows developers with memory issues who can buy your software.

Standardized proprietary platforms can lead to massive profit returns for the platform provider. In 1995, Windows was such a good platform that Microsoft could sell a CD in a cardboard box for $100. In 2018, the iPhone is so good that Apple can take 30% from all app sales on its platform.

Proprietary standards lead to fragmentation.

Your iPhone app does not run on my Kindle Fire. I can’t use your Snapchat augmented reality sticker on Facebook Messenger. My favorite digital audio workstation only runs on Windows–so I have to keep a Windows computer around just to make music.

When developers see this fragmentation, they groan. They imagine the greedy capitalists, who are making money at the expense of software quality.  Developers think, “why can’t we all just get along? Why can’t we have things be open and free?”

Developers think, “we don’t need proprietary standards. We can have open standards.”

Growth of Apache, part of the LAMP (Linux, Apache, MySQL, PHP) Stack

This happened with Linux. These days, new server side applications are mostly in Linux. There was a time when that was controversial (see the far left hand side of chart above).

More recently, we saw a newer open standard with Docker. Docker gave us an open, standardized way of packaging, deploying, and distributing a single node. This was hugely valuable! But for all of the big problems that Docker solved, it highlighted a new problem–how should we be orchestrating these nodes together?

After all–your application is not just a single node. You know you want to be deploying a Docker container–but how are your containers communicating with each other? How are you scaling up instances of these containers? How are you routing traffic between container instances?

After Docker became popular, a scramble of open source projects and proprietary platforms emerged to solve the problem of container orchestration.

Mesos, Docker Swarm, and Kubernetes each offered a different set of abstractions for managing containers. Amazon ECS offered a proprietary managed service that took care of installation and scaling of Docker containers for AWS users.

Some developers did not adopt any orchestration platform, and used BASH, Puppet, Chef, and other tools to script their deployments.

Whether a developer was deploying their container by using an orchestration platform or a script, Docker sped up development, and made things more harmonious between developers and operations.

As more developers deployed containers with Docker, the importance of the orchestration platform was becoming clear. A container is as fundamental to a distributed system as an object is to an object oriented program. Everyone wanted to be using a container platform, but there was a struggle between these platforms, and it was hard to see which would come out on top–or if it would be a decades long struggle, like iOS vs. Android.

This struggle between the different container orchestration platforms was causing fragmentation–not because any of the popular orchestration frameworks were proprietary (Swarm, Kubernetes, and Mesos are all open source), but because each container orchestration community had invested so much in their own system.

So, from 2013 – 2016, there was some anxiety among Docker power users. Choosing a container orchestration framework is a huge bet–and if you chose the wrong orchestration system, it would be like opening a movie store and choosing HD DVD over Blu-ray.

These pictures of container ships falling over never get old. Image: Huffington Post

The war between container orchestrators felt like a winner-take-all affair.

And as in any war, there was a fog that was hard to see through. When I was reporting on container orchestration wars, I recorded podcast after podcast with container orchestration experts, where I would ask some form of the question, “so, which container orchestration system is going to win?”

I did this until someone I respect told me that asking about who was going to “win the orchestration wars” was a less interesting question than evaluating the technical tradeoffs between the orchestrators.

Looking back, I regret buying into the narrative of a war between container orchestrators.

As the debates about container orchestrators raged on, the smartest people in the room were mostly having calm, scientific discussions–even when reporters like me were getting worked up, and thinking that this was a story about tribalism.

The conflicts between container orchestrators were not about tribalism–they were more about differences of opinion, and developer ergonomics.

OK, maybe the container orchestration war wasn’t only about differences of opinion. There is a boatload of money to be made in this space. We are talking about contracts with billion dollar legacy organizations–banks, and telcos, and insurance companies–who are making their way onto the cloud.

If you are in the business of helping telcos move onto the winning platform, business is good. If you champion the wrong platform, you end up with a warehouse full of HD-DVDs.

The time where the conflict was the worst was near the end of 2016, when there were rumors about Docker potentially forking, so that Docker the company could change the Docker standard to fit better with their container orchestration system Docker Swarm–but even in those times, it would have made sense to be an optimist.

Creative destruction is painful, but it is a sign of progress–and in the struggle for container orchestration dominance, there was a ton of creative destruction.

And when the dust cleared around the end of 2016, Kubernetes was the clear winner.

Today, with Kubernetes becoming the safe choice, CIOs feel more comfortable adopting container orchestration at their enterprises–which makes vendors feel more comfortable investing in Kubernetes-specific tools to sell to those CIOs.

This brings us to the present:

Today, the most lucrative provider of proprietary backend developer infrastructure is Amazon Web Services. Developers do not view AWS resentfully, because AWS is innovative, empowering, and cheap. If you are paying AWS a lot of money, that probably means your business is doing well.

With AWS, developers do not feel the level of lock-in that was administered by the dominant proprietary platforms of the 90s. But there is some lock-in. Once you are deeply embedded in the AWS ecosystem, using services like DynamoDB, Amazon Elastic Container Service, or Amazon Kinesis, it becomes a daunting task to move away from Amazon.

With Kubernetes creating an open, common layer for infrastructure, it becomes theoretically possible to “lift and shift” your Kubernetes cluster from one cloud provider to another.

If you decided to lift-and-shift your application, you would have to rewrite parts of your application to stop using the Amazon-specific services (like Amazon S3). For example, if you wanted an S3 replacement that would run on any cloud, you could configure a Kubernetes cluster with Rook, and start to store objects on Rook with the same APIs that you would use to store them on S3.

This is a nice option to have, but I have not yet heard of anyone actually lifting and shifting their application away from a cloud–except for Dropbox, and their migration was so epic it took two and a half years.

Certainly there is someone out there other than Dropbox who spends so much money on Amazon S3 that they will consider spinning up their own object store, but it would be a huge effort to do such a migration.

(Kubernetes can be used for lifting and shifting–but more likely will be used to have familiar operating layer in different clouds)

Kubernetes probably won’t be a tool for widespread lifting and shifting any time soon. A more likely scenario is that Kubernetes will become a ubiquitous control plane, that enterprises will use on multiple clouds.

NodeJS is a useful analogy. Why do people like NodeJS for their server side applications? It’s not necessarily because Node is the fastest web server. It’s because people like to use the same language on both the client and the server. Just like NodeJS lets you move between your client and server code without having to switch languages, Kubernetes will let you switch between clouds without having to change how you think about operations.

On each cloud, you will have some custom application code running on Kubernetes that interacts with the managed services provided by that cloud.

Companies want to be multi-cloud–partly for disaster recovery, but also because there is actual upside to having access to managed services on the different clouds.

One emerging pattern is to split infrastructure between AWS for user traffic and Google Cloud for data engineering. One company that uses this pattern is Thumbtack:

At Thumbtack, the production infrastructure on AWS serves user requests. The log of transactions that occur get pushed from AWS to Google Cloud, where the data engineering occurs. On Google Cloud, the transaction records are queued in Cloud PubSub, a message queueing service. Those transactions are pulled off the queue and stored in BigQuery, a system for storage and querying of high volumes of data.
\n
\nBigQuery is used as the data lake to pull from when orchestrating machine learning jobs. These machine learning jobs are run in Cloud Dataproc, a managed service that runs Apache Spark. After training a model in Google Cloud, that model is deployed on the AWS side, where it serves user traffic. On the Google Cloud side, the orchestration of these different managed services is done by Apache Airflow, an open source tool that is one of the few pieces of infrastructure that Thumbtack does have to manage themselves on Google Cloud.

Today, Thumbtack uses AWS for serving user requests and Google Cloud for data engineering and queueing in PubSub. Thumbtack trains its machine learning models in Google, and deploys them to AWS.

This is just the way things are today. Thumbtack might eventually use Google Cloud for user-facing services as well.

(a multi-cloud data engineering pipeline from a Japanese company)

More companies will gradually move towards multiple clouds–and some of them will manage a unique Kubernetes cluster on each cloud.

You might have a GKE Kubernetes cluster on Google to orchestrate workloads between BigQuery, Cloud PubSub, and Google Cloud ML, and you might have an Amazon EKS cluster to orchestrate workloads between DynamoDB, Amazon Aurora, and your production NodeJS application.

Cloud providers are not replaceable commodities. The services provided by the different clouds will get increasingly exotic and differentiated. Enterprises will benefit from having access to the different services on the different cloud providers.

Services like Google BigQuery and AWS Redshift are popular because they give you a powerful, scalable, multi-node tool with a simple API. Developers often choose these managed services because they are so easy to use.

You don’t see these types of paid tools for single nodes. I don’t pay for NodeJS, or React, or Ruby on Rails.

Tools for a single node are much easier to operate than tools for a distributed system. It’s harder to deploy Hadoop across servers than to run a Ruby on Rails application on my laptop. With Kubernetes, this is going to change.

If you are using Kubernetes, you can use a distributed systems package manager called Helm. This is like npm for Kubernetes applications. If you are using Kubernetes, you can use Helm to easily install a complicated multi-node application, no matter what cloud provider you are on.

Here’s a description of Helm:

A package manager for distributed systems. Amazing! Let’s take a look at what I can install.

Not pictured: WordPress, Jenkins, Kafka

Distributed systems are hard to set up. Ask anyone who has set up their own Kafka cluster. Helm is going to make installing Kafka as easy as installing a new version of Photoshop on your MacBook. And you will be able to do this on any cloud.

Before Helm, the closest thing to a distributed systems package manager (that I am aware of) was the marketplace that you find on AWS or Azure, or the Google Cloud Launcher. Here again we see how proprietary software can lead to fragmentation. Before Helm, there was no standard, platform-agnostic way of one-click installing Kafka.

You can find a way to one-click install Kafka on AWS, Google, or Azure. But each of these installations had to be written independently, for that specific cloud provider. And to install Kafka on Digital Ocean, you need to follow a 10-step tutorial.

Helm represents a cross-platform system for distributing multi-node software on any Kubernetes instance. You could use an application installed with Helm in any cloud provider or on your own hardware. You could easily install Apache Spark or Cassandra–systems that are notoriously difficult to set up and operate.

Helm is a package manager for Kubernetes–but it also looks like the beginnings of an app store for Kubernetes. With an app store, you could sell software for Kubernetes.

What kind of software could you sell?

You could sell enterprise distributions of distributed systems platforms like Cloudera Hadoop, Databricks Spark, and Confluent Kafka. New monitoring systems like Prometheus and multi-node databases like Cassandra that are hard to install.

Maybe you could even sell higher-level, consumer-grade software like Zendesk.

The idea of a self-hosted Zendesk sounds crazy, but someone could build that, and sell it in the form of a proprietary binary, at the cost of a flat fee instead of a subscription. If I sell you a $99 Zendesk-for-Kubernetes, and you can easily run it on your Kubernetes cluster on AWS, you are going to end up saving a lot of money on support ticketing software.

Enterprises often run their own WordPress to manage a company blog. Is the software for Zendesk that much more complicated than WordPress? I don’t think so–but enterprises are much more scared of managing their own help desk software than managing their own blogging software.

I run a pretty small business but I subscribe to a LOT of different software-as-a-service tools. An expensive WordPress host, an expensive CRM for advertising sales, MailChimp for the newsletter. I pay for these services because they are super reliable and secure, and they are complex multi-node applications. I wouldn’t want to host my own. I wouldn’t want to support them. I don’t want to be responsible for technical troubleshooting when my newsletter fails to send. I want to run less software.

In contrast, I’m not afraid that my single-node software is going to break.

Software that I use from a single node tends to be much less expensive because I don’t have to buy it as a “service”. The software that I use to write music has a 1-time fixed cost. Photoshop has a 1-time fixed cost. I pay for the electricity to run my computer, but other than that I have no ongoing capital expense to run Photoshop.

When multi-node applications are as reliable as single-node applications, we will see changes in the pricing models.

Maybe someday I will be able to purchase a Zendesk-for-Kubernetes. The Zendesk-for-Kubernetes will give me everything I need from a help desk–it will spin up an email server, it will give me a web frontend to manage tickets. And if anything goes wrong, I can pay for support when I need it.

Zendesk is a fantastic service–but it would be cool if it had a fixed pricing model

With Kubernetes, it becomes easier to deploy and manage distributed applications. With Helm, it becomes easier to distribute those applications to other users. But it’s still pretty hard to develop distributed systems.

This was the focus of a recent CloudNative Con/KubeCon Keynote by Brendan Burns, called “This Job is Too Hard: Building New Tools, Patterns, and Paradigms to Democratize Distributed Systems Development”.

In his presentation, Brendan presented a project called Metaparticle. Metaparticle is a standard library for cloud-native development, with the goal of democratizing distributed systems. In an introduction to Metaparticle, Brendan wrote:

After decades of distributed systems research and application, patterns have emerged about how we build these systems. We need a way to do locking of a variable, so that two nodes will not be able to write to that variable in a nondeterministic fashion. We need a way to do master election, so that if the master node dies, the other nodes can pick a new node to orchestrate the system.

Today, we use tools like etcd and Zookeeper to help us with master election and locking–and these tools have an onboarding cost.

Brendan illustrates this with the example of Zookeeper, which is used by both Hadoop and Kafka to do master election. Zookeeper takes significant time and effort to learn how to operate. During the construction of both Hadoop and Kafka, the founding engineers of those projects engineered their systems to work with Zookeeper to maintain a master node.

If I am writing a system to do distributed mapreduce, I would like to avoid thinking about node failures and race conditions. Brendan’s idea is to push those problems down into a standard library–so the next developer who comes along with a new idea for a multi-node application has an easier time.

Important meta-point: metaparticle is built with the assumption that you are on Kubernetes. This is a language-level abstraction that is built with an assumption about the underlying (distributed) operating system–which once again brings us back to standards. If everyone is on the same distributed operating system, we can make big assumptions about the downstream users of our projects.

This is why my mind is blown by Kubernetes. It is a layer of standards across a world of heterogeneous systems.

Functions as a service (often called “serverless” functions) are a powerful, cheap abstraction that developers can use alongside Kubernetes, on top of Kubernetes, and in some cases instead of Kubernetes altogether.

Let’s quickly review the modern landscape of serverless applications, and then consider the relationship between serverless and Kubernetes.

Quick review on functions as a service:

Functions as a service are deployable functions that run without an addressable server.

Functions as a service deploy, execute, and scale with a single call by the developer. Until you make that call to the serverless function, your function is not running anywhere–so you are not using up resources other than the database that is storing your raw code. When you call a function as a service, your cluster will take care of scheduling and running that function.

You don’t have to worry about spinning up a new machine and monitoring that machine, and spinning the machine down once it becomes idle. You just tell the cluster that you want to run a function, and the cluster executes it and returns the result.

When you “deploy” a serverless function, the function code is not actually deployed. Your code sits in a database in plain text. When you call the function, your code is being taken out of the database entry, loaded onto a Docker container, and executed.

(diagram from https://medium.com/openwhisk/uncovering-the-magic-how-serverless-platforms-really-work-3cb127b05f71)

AWS Lambda pioneered this idea of a function-as-a-service in 2014. Since then, developers have been thinking of all kinds of use cases. For a comprehensive list of how developers are using serverless, there is a shared Google Doc created by the CNCF Serverless Working Group (34 pages at the time of this article).

From my conversations on Software Engineering Daily, these functions as a service have shown at least two clear applications:

To create a FaaS platform, a cloud provider provisions a cluster of Docker containers called invokers. Those invokers wait to get blobs of code scheduled onto them. When you make a request for your code to execute, there is a period of time that you have to wait for that code to be loaded onto an invoker and executed. This time spent waiting is the “cold start” problem.

The cold start problem is one of the tradeoffs that you make if you decide to run part of your application on FaaS. You don’t pay for the uptime of a server that isn’t doing any work–but when you want to call your function, you have to wait for your code to be scheduled onto an invoker.

On AWS there are invokers designated for whatever requests for AWS Lambda come in. On Microsoft Azure there are invokers designated for Azure Functions requests. On Google Cloud there are invokers reserved for Google Cloud Functions.

For most developers, using the function-as-a-service platforms from AWS, Microsoft, Google, or IBM will be fine. The costs are low, and the cold start problem is not problematic for most applications. But some developers will want to get costs even lower. Or they might want to write their own scheduler that defines how code gets scheduled onto invoker containers. These developers can roll their own serverless platform.

Open source FaaS projects such as Kubeless let you provision your own serverless cluster on top of Kubernetes. You can define your own pool of invokers. You can determine how containers are scheduled against jobs. You can decide on how to solve the cold start problem for your own cluster.

The open source FaaS for Kubernetes are just one type of resource scheduler. They are just a preview of other custom schedulers we will see on top of Kubernetes. Developers are always building new schedulers in order to build more efficient services on top of those schedulers.

So–what other types of schedulers will be built on top of Kubernetes? Well, as they say, the future is already here, but it’s only available as an AWS managed service.

AWS has a new service called Amazon Aurora Serverless–which is a database that scales storage and compute up and down automatically. From Jeff Barr’s post about AWS Serverless Aurora:

When you create an Aurora Database Instance, you choose the desired instance size and have the option to increase read throughput using read replicas. If your processing needs or your query rate changes you have the option to modify the instance size or to alter the number of read replicas as needed. This model works really well in an environment where the workload is predictable, with bounds on the request rate and processing requirement.

In some cases the workloads can be intermittent and/or unpredictable, with bursts of requests that might span just a few minutes or hours per day or per week. Flash sales, infrequent or one-time events, online gaming, reporting workloads (hourly or daily), dev/test, and brand-new applications all fit the bill. Arranging to have just the right amount of capacity can be a lot work; paying for it on steady-state basis might not be sensible.

Because storage and processing are separate, you can scale all the way down to zero and pay only for storage. I think this is really cool, and I expect it to lead to the creations of new kinds of instant-on, transient applications. Scaling happens in seconds, building upon a pool of “warm” resources that are raring to go and eager to serve your requests.

We are not surprised that AWS can build something like this, but it’s hard to imagine how it could emerge as an open source project—until Kubernetes. This is the type of system that random developers could build on top of Kubernetes.

If you wanted to build your own serverless database on top of Kubernetes, you’ve got a number of scheduling problems to solve. You need different resource tiers for networking, storage, logging, buffering, and caching. For each of those different resource tiers, you need to define how resources will get scheduled to scale up and down in response to demand.

Just like Kubeless offers a scheduler for the small bits of functional code, we might see other custom schedulers that people use as building blocks for bigger applications.

And once you actually build your serverless database, perhaps you could sell it on the Helm app store as a $99 one-time purchase.

I hope you have enjoyed this tour through some Kubernetes history and speculation about the future.

As 2018 begins, here are some of the areas we’d like to explore this year:

Kubernetes is a fantastic tool for building modern application backends–but it is still just a tool.

If Kubernetes fulfills its mission, it will eventually fade into the background. There will come a time when we talk about Kubernetes like we talk about compilers or operating system kernels. Kubernetes will be lower level plumbing that is not in the purview of the average application developer.

But until then, we’ll continue to report on it.

", + "Episodes Title": "The Gravity of Kubernetes", + "Episodes Uid": "SED3271186908", + "Episodes Audio File": "45af777d44ea547d35e3c4e68ea890b8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23e", + "Episodes ID": "18ded8fa-e329-11ea-91a2-ab12d8821691", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/android_on_iphone_fixed.mp3", + "Episodes Pubdate Date": "2016-07-22", + "Episodes Summary": "

Finally–the Android operating system has been put on an iPhone, and today’s guest is Nick Lee, who accomplished that feat. Nick works at Tendigi, a design and engineering firm.

In the past, Nick has put Windows 95 on an Apple Watch. Why would you do something like this? In today’s interview with Nick, we talk about the technical challenges of bringing Nick’s bizarre sense of technological irony into reality.

", + "Episodes Title": "Android on iPhone with Nick Lee", + "Episodes Uid": "SED1070180178", + "Episodes Audio File": "4ba57d2207e27cdb25f062a15307b7b9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "24n", + "Episodes ID": "1733f120-e329-11ea-91a2-03eddca7bc06", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/unik_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-08-11", + "Episodes Summary": "

The Linux kernel of many popular operating system distributions contains 200-500 million lines of code. The average user never touches many of the libraries that are contained in these operating system distributions. For example, if you spin up a virtual machine on a cloud service provider, the virtual machine will have a USB driver. This is wasted space, because you can’t even interact with the USB port on a virtual machine.

Unikernels are a way to rethink our usage of operating systems. A unikernel uses a stripped down operating system called a library operating system–it contains only the libraries you need for the applications you are running. Today’s guest Scott Weiss joins the show to talk about unikernels, and a project he is working on called UniK, a tool for compiling application sources into unikernels.

", + "Episodes Title": "unikernels and unik with Scott Weiss", + "Episodes Uid": "SED6678239519", + "Episodes Audio File": "a1f10131e6dff4438a96e4943d811a90.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 238, + "Episodes ID": "1983ee3a-e329-11ea-91a2-1b3f85583b58", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/IOT_Analytics_edited.mp3", + "Episodes Pubdate Date": "2016-07-13", + "Episodes Summary": "

On smart thermostats, sensor-driven assembly lines, and electronically monitored farms, the internet of things is producing huge volumes of data.

To take advantage of that data, an application needs tools for storing and analyzing that data. Today’s guest is Jean-Cristophe Cimono, the CTO of mnubo, a cloud platform for connected objects. Today we walk through the architecture of mnubo and the use cases of an IoT analytics platform.

Thanks to Manuel Vonthron and Eduardo Siman for contributing to the preparation of this show.

", + "Episodes Title": "IoT Analytics with Jean-Christophe Cimono", + "Episodes Uid": "SED4675148630", + "Episodes Audio File": "b10d6dc9745ae27817b469de63f58bdf.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "yc", + "Episodes ID": "2c707914-e329-11ea-91a2-8b4e634fa778", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SQLite.mp3", + "Episodes Pubdate Date": "2015-11-13", + "Episodes Summary": "

SQLite is an SQL database engine that can be used in applications as a library for quick read-write operations. Unlike other database management systems, SQLite is not a client-server database designed to run in a data center.

D. Richard Hipp is the architect and primary author of SQLite and the Fossil SCM.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "SQLite with D. Richard Hipp", + "Episodes Uid": "SED6614092294", + "Episodes Audio File": "0c4a0a386a48093eb21644382ff01a77.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "rz", + "Episodes ID": "2fd72c42-e329-11ea-91a2-e765057b8252", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/pachyderm_loud.mp3", + "Episodes Pubdate Date": "2015-10-11", + "Episodes Summary": "

Pachyderm is a containerized data analytics platform that seeks to replace Hadoop.

Joe Doliner is the Co-founder and CEO of Pachyderm. Previously he worked as a software engineer at RethinkDB and AirBnB.

", + "Episodes Title": "Replacing Hadoop with Joe Doliner", + "Episodes Uid": "SED7433145361", + "Episodes Audio File": "6b02d1f3f9c4679537eb35cbba48649a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "34j", + "Episodes ID": "f6173dd0-e328-11ea-91a2-238279a48f3a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/BuildaBlockchain.mp3", + "Episodes Pubdate Date": "2017-10-12", + "Episodes Summary": "

A blockchain is a data structure that provides decentralized, peer-to-peer data distribution. Bitcoin is the most well-known blockchain, but in the next decade we will see many more blockchains. Most listeners probably know that you could just fork the code of Bitcoin to start your own blockchain–but wouldn’t it be nice to know how to build a blockchain from scratch?

Daniel van Flymen is the author of the Medium article Learn Blockchains by Building One. In his post, he walks you through how to write the code for a blockchain–just like any other web app. He starts with raw Python code, defines the data structures, and stands up his simple blockchain app on a web server to give a toy example for how nodes in a blockchain communicate.

For me, this was a great article to read. I have reported on blockchains for over a year, but had not seen such a clear example with executable, simplified code.

Stay tuned at the end of the episode for Jeff Meyerson’s tip about making the most of a new job: brought to you by Indeed Prime.

To find all of our coverage of cryptocurrencies, download the Software Engineering Daily app for iOS or Android to hear all of our old episodes. They are easily organized by category, and as you listen, the SE Daily app gets smarter, and recommends you content based on the episodes you are hearing. If you don’t like this episode, you can easily find something more interesting by using the recommendation system.

The mobile apps are open sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to hack on, we would love to get your help! We are building a new way to consume software engineering content. We have the Android app, the iOS app, a recommendation system, and a web frontend–and more projects are coming soon. If you have ideas for how software engineering media content should be consumed, or if you are interested in contributing code, check out github.com/softwareengineeringdaily, or join our Slack channel (there’s a link on our website)–or send me an email: jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Blockchain Building with Daniel van Flymen", + "Episodes Uid": "SED4558637599", + "Episodes Audio File": "56fc8a6ce93dd07d6ec054d98e623509.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2v3", + "Episodes ID": "f755a3f8-e328-11ea-91a2-3350faf7a129", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CoinbaseCurrencies.mp3", + "Episodes Pubdate Date": "2017-07-12", + "Episodes Summary": "

Cryptocurrencies have seen a surge of value recently. People are starting to see that bitcoin, ethereum, and other currencies are not just for speculation. At worst, they are a store of value–like digital gold. At best, they are a tool for micropayments, smart contracts, and an entire decentralized financial platform.

Coinbase is a company for buying and selling cryptocurrencies. This episode is the first of three interviews with different members of Coinbase. In this episode, Linda Xie and Jordan Clifford explain why cryptocurrencies are important, and how products that Coinbase builds make cryptocurrencies easier to use.

This is the first in a series of episodes about Coinbase. Tomorrow we will discuss antifraud with Soups Ranjan, director of data science at Coinbase. We’d love to hear your thoughts on this series, and any other suggestions or feedback you have. Send me an email–jeff@softwareengineeringdaily.com

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Coinbase Currencies with Linda Xie and Jordan Clifford", + "Episodes Uid": "SED1735004573", + "Episodes Audio File": "bf0f990c8b86a5b6b35f71cb2886e4cb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "28b", + "Episodes ID": "12b6a886-e329-11ea-91a2-73d5c9277f13", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/pancakestack_edited_fixed.mp3", + "Episodes Pubdate Date": "2016-10-17", + "Episodes Summary": "

Data engineering is the software engineering that enables data scientists to work effectively. In today’s episode, we explore the different sides of data engineering–the data science algorithms that need to be processed and the implementation of software architectures that enable those algorithms to run smoothly.

The PANCAKE STACK is a 12-letter acronym that Chris Fregly gave to a collection of data engineering technologies including Presto, Cassandra, Kafka, Elastic Search, and Spark. In his current life, Chris travels around the world giving workshops on how to deploy and use the PANCAKE STACK. Before that, he was an engineer at Netflix, where he received an Emmy for Streaming Engineering Excellence.

", + "Episodes Title": "PANCAKE STACK Data Engineering with Chris Fregly", + "Episodes Uid": "SED2128450463", + "Episodes Audio File": "ec038279123092ac5b3d16cf7d62ab21.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4ym", + "Episodes ID": "f07b7d50-e328-11ea-91a2-4f62a96eb6bd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Negotiation_Edited.mp3", + "Episodes Pubdate Date": "2018-11-20", + "Episodes Summary": "

Featured Image Photo Credits

Originally posted on July 11, 2016.

Negotiation is an important skill for software engineers. The salary you negotiate at the beginning of your job could be a difference of tens of thousands of dollars over the course of an engineer’s career, but intimidating recruiters and exploding offers scare many engineers from negotiating at all.

Today, Haseeb Qureshi returns to the show to discuss his epic story of salary negotiation. On a previous episode, Haseeb discussed leaving his career as a poker player to join a coding boot camp and start down the path of a software engineer.

In this episode and his recent blog post, Haseeb describes his approach to the job search and salary negotiation process, which eventually landed him at Airbnb with a $250,000 annual salary–after about a year of learning to code.

", + "Episodes Title": "Salary Negotiation with Haseeb Qureshi Holiday Repeat", + "Episodes Uid": "SED8203864529", + "Episodes Audio File": "d9d2326663008632093810d517b86cca.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 231, + "Episodes ID": "19cf64d2-e329-11ea-91a2-2bf756b2b67d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Platforms.mp3", + "Episodes Pubdate Date": "2016-07-11", + "Episodes Summary": "

At software conferences, I like to walk around the vendor booths and talk to the representatives from different companies. By talking to the vendors about their marketing pitches, I get an idea of how those companies are positioning themselves for the future, and the complex business landscape of software becomes slightly easier to understand.

At recent conferences, many of the big vendors have been talking about their cloud platform. With Cloud Foundry, OpenShift, Kubernetes, OpenStack and so many other cloud platforms, it is hard to keep track of the different offerings, and how they differentiate. Bridget Kromhout joins the show today to talk about these different platforms, and how they have changed modern software development. We also talk about her podcast Arrested DevOps, a great show where she interviews some of the luminaries of the operations and software development world.

You can also hear Bridget speak at O’Reilly’s Velocity 2016 conference in New York.
\nWe are giving away a free ticket to Velocity New York. If you want to be entered to win that ticket, send a tweet about your favorite SE Daily episode about dev ops or web performance, and tag software_daily, as well as #velocityconf.

", + "Episodes Title": "Platforms with Bridget Kromhout", + "Episodes Uid": "SED8487107100", + "Episodes Audio File": "4153c7121b3a8d63a0248903010cf286.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "22c", + "Episodes ID": "19c90ee8-e329-11ea-91a2-27e17aa0d313", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Negotiation_Edited.mp3", + "Episodes Pubdate Date": "2016-07-12", + "Episodes Summary": "

Negotiation is an important skill for software engineers. The salary you negotiate at the beginning of your job could be a difference of tens of thousands of dollars over the course of an engineer’s career, but intimidating recruiters and exploding offers scare many engineers from negotiating at all.

Today, Haseeb Qureshi returns to the show to discuss his epic story of salary negotiation. On a previous episode, Haseeb discussed leaving his career as a poker player to join a coding boot camp and start down the path of a software engineer.

In this episode and his recent blog post, Haseeb describes his approach to the job search and salary negotiation process, which eventually landed him at Airbnb with a $250,000 annual salary–after about a year of learning to code.

", + "Episodes Title": "Salary Negotiation with Haseeb Qureshi", + "Episodes Uid": "SED1250146209", + "Episodes Audio File": "d9d2326663008632093810d517b86cca.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "23a", + "Episodes ID": "18ce4c38-e329-11ea-91a2-efd3b95ad650", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/OSCON_edited.mp3", + "Episodes Pubdate Date": "2016-07-25", + "Episodes Summary": "

Open source software has become the rule for how software is written rather than the exception. OSCON is O’Reilly’s open source conference, where companies and individuals talk about where the open-source world is going.

Rachel Roumeliotis is the chair of OSCON, and she joins the show today to talk about the state of open source, and how the conference has developed since she started working at O’Reilly.

We are giving away a free ticket to O’Reilly’s Velocity 2016 conference in New York. If you want to be entered to win that ticket, send a tweet about your favorite SE Daily episode about dev ops or web performance, and tag software_daily, as well as #velocityconf.

", + "Episodes Title": "Open Source Culture with Rachel Roumeliotis", + "Episodes Uid": "SED7286529355", + "Episodes Audio File": "dfdd6773e2bd9755aeb2a9b8aaac9e47.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1y5", + "Episodes ID": "1d9f3bdc-e329-11ea-91a2-ff9d1526fdf6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Brian_Holt.mp3", + "Episodes Pubdate Date": "2016-05-03", + "Episodes Summary": "

At Netflix, building a user interface requires data about movies, actors, users, accounts, and much more. If each piece of data is coming from a different source, a programmer has to call each of the services that has access to that data. Falcor is a piece of technology designed at Netflix to solve this problem.
\nFalcor creates a unified JSON model of all of the data you could want–and Netflix engineer Brian Holt joins us today to discuss how Falcor works. We also discuss React, ES6, and JavaScript at Netflix, and Brian explains why Falcor is extremely similar to GraphQL, and why that is OK.

", + "Episodes Title": "Falcor at Netflix with Brian Holt", + "Episodes Uid": "SED6516737058", + "Episodes Audio File": "f421b8d7f4b1689fc401916b24a396d0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 318, + "Episodes ID": "f699a342-e328-11ea-91a2-43d5e7a1660f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SalesforceEinstein.mp3", + "Episodes Pubdate Date": "2017-09-05", + "Episodes Summary": "

Software companies that have been around for a decade have a ton of data. Modern machine learning techniques are able to turn that data into extremely useful models. Salesforce users have been entering petabytes of data into the company’s CRM tool since 1999. With its Einstein suite of products, Salesforce is using that data to build new product features and APIs.

Simon Chan is the senior director of product management with Einstein. He oversees the efforts to give longtime Salesforce customers new value, and the efforts to build brand new APIs for image recognition and recommendation systems, which can form the backbone of entirely new businesses.

Companies spend billions of dollars on sales and marketing, and I wanted to understand where the best opportunities for Salesforce were. Simon and I spent much of our time exploring higher level applications, but we got to lower level engineering eventually.

There are 600 episodes of Software Engineering Daily, and it can be hard to find the shows that will interest you. If you have an iPhone and you listen to a lot of Software Engineering Daily, check out the Software Engineering Daily mobile app in the iOS App Store. Every episode can be accessed through the app, and we give you recommendations based on the ones you have already heard.

", + "Episodes Title": "Artificial Intelligence APIs with Simon Chan", + "Episodes Uid": "SED5671295199", + "Episodes Audio File": "02dd439c05277df02bb65f0c0b26fdf4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1yc", + "Episodes ID": "1d206e56-e329-11ea-91a2-33cd8b466d8f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/React_Data.mp3", + "Episodes Pubdate Date": "2016-05-10", + "Episodes Summary": "

React started as just a view layer–it was the V in MVC. React has moved down the stack, with Flux, Redux, GraphQL, and Relay providing opinions for how React applications should structure their data flow.

Jared Forsyth works at Khan Academy, which uses React on the front end. At Khan Academy, Jared has experimented with many different ways of handling data flow for a React application, and in today’s episode we not only discuss the conventional tools for React applications, but also ClojureScript, Reframe, and Om/next, which are solutions for React data handling, that are outside of the world of raw JavaScript.

", + "Episodes Title": "React Data Flow with Jared Forsyth", + "Episodes Uid": "SED6003566226", + "Episodes Audio File": "04513471023716f3c82183f3d7a6f078.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "px", + "Episodes ID": "30b41fee-e329-11ea-91a2-2f413b924e7b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ben_hamner.mp3", + "Episodes Pubdate Date": "2015-10-03", + "Episodes Summary": "

Kaggle is a platform for data scientists to collaborate and compete on machine learning problems with the opportunity to win money from the competitions’ sponsors.

Ben Hamner is the co-founder and CTO of Kaggle.

", + "Episodes Title": "Kaggle with Ben Hamner", + "Episodes Uid": "SED7358221953", + "Episodes Audio File": "81eba8f887fee79b48d9189ca322262a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "9t", + "Episodes ID": "36e3441c-e329-11ea-91a2-63a73485647e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/christian_ander_goobit.mp3", + "Episodes Pubdate Date": "2015-08-15", + "Episodes Summary": "

Christian Ander is CEO of Goobit AB.

", + "Episodes Title": "Bitcoin Meets Banks with Christian Ander", + "Episodes Uid": "SED1604123463", + "Episodes Audio File": "a1bd40059fd0af96d6f2a71cf9f7a763.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "pf", + "Episodes ID": "30c0d1a8-e329-11ea-91a2-27601123f164", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/edwin_chen.mp3", + "Episodes Pubdate Date": "2015-10-02", + "Episodes Summary": "

Many companies find themselves drowning in data. The quantity of data matters far less than the right questions in the pursuit of actionable insights.

Edwin Chen is a data scientist and blogger. He previously led data science teams at Dropbox and Google.

", + "Episodes Title": "Applied Data Science with Edwin Chen", + "Episodes Uid": "SED7365914999", + "Episodes Audio File": "786ec8e3171eab9373dfc8f875d21084.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ea", + "Episodes ID": "357649bc-e329-11ea-91a2-a3168c41ca3f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/docker_turnbull.mp3", + "Episodes Pubdate Date": "2015-08-28", + "Episodes Summary": "

Docker containers wrap up a piece of software in a complete filesystem that contains everything it needs to run. This allows for quick flexibility and scaleability in business applications, a key driver of the DevOps methodology.

James Turnbull is VP of engineering at Kickstarter, an advisor at Docker and author of The Docker Book.

", + "Episodes Title": "Docker and Microservices with James Turnbull", + "Episodes Uid": "SED3276366538", + "Episodes Audio File": "03a6e8146725df7e1518d45854dc521c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "kn", + "Episodes ID": "328949c0-e329-11ea-91a2-3b9c0d28acf0", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/nickschrock.mp3", + "Episodes Pubdate Date": "2015-09-19", + "Episodes Summary": "

These technologies complement the paradigm shift of React and other Facebook technologies.

Nick Schrock is the co-creator of GraphQL and an engineer on product infrastructure at Facebook.

", + "Episodes Title": "GraphQL and Relay with Nick Schrock", + "Episodes Uid": "SED2156288962", + "Episodes Audio File": "b77a1061682869f1bba605233ea680df.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "o5", + "Episodes ID": "317af0e2-e329-11ea-91a2-8f027f3c4b1c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/janice_chicktech.mp3", + "Episodes Pubdate Date": "2015-09-25", + "Episodes Summary": "

ChickTech: High School builds girls’ confidence, teaches them vital skills, and introduces them to a wide range of technological interests, from robotics to game design to programming.

Janice Levenhagen is the Founder and Executive Director of ChickTech.

", + "Episodes Title": "ChickTech with Janice Levenhagen", + "Episodes Uid": "SED9862456310", + "Episodes Audio File": "cf06a164441bc4da501194c9704865c5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ow", + "Episodes ID": "3117bd10-e329-11ea-91a2-5bc52e1c2526", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/vik_paruchuri.mp3", + "Episodes Pubdate Date": "2015-09-30", + "Episodes Summary": "

Dataquest is an in-browser platform for learning data science that is tackling this problem.

Vik Paruchuri is the founder of Dataquest. He was previously a machine learning engineer at EdX and before that a U.S. diplomat.

", + "Episodes Title": "Teaching Data Science with Vik Paruchuri", + "Episodes Uid": "SED3468302553", + "Episodes Audio File": "a4b46114dfad49c00dd52bd96b000147.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "eq", + "Episodes ID": "35518686-e329-11ea-91a2-bfa2b53aae3d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/nationwide.mp3", + "Episodes Pubdate Date": "2015-08-29", + "Episodes Summary": "

Carmen DeArdo is technology director at Nationwide Insurance.

", + "Episodes Title": "DevOps at Nationwide Insurance with Carmen DeAdro", + "Episodes Uid": "SED7447733050", + "Episodes Audio File": "a79e77dc831f3cd75da2eeee4d07b440.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "n7", + "Episodes ID": "32035a7c-e329-11ea-91a2-2f958640a4ca", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/preethi_kasireddy.mp3", + "Episodes Pubdate Date": "2015-09-23", + "Episodes Summary": "

Former Andreesen-Horowitz partner Preethi Kasireddy saw excited software engineers coming through the doors every day, pitching their ideas.

This was her impetus to take the leap and make the career switch to software engineering. She is attending Hack Reactor, a 12-week coding boot camp.

", + "Episodes Title": "Venture Capital to Software Engineering with Preethi Kasireddy", + "Episodes Uid": "SED8594022727", + "Episodes Audio File": "07c7139cfa9b67daa5927906592ad757.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 47, + "Episodes ID": "37e1f052-e329-11ea-91a2-cfdf539c75aa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/node_yunong_fixed.mp3", + "Episodes Pubdate Date": "2015-08-01", + "Episodes Summary": "

Yunong Xiao is a senior engineer at Netflix. He works on the website’s Node.js front-end and middle-tier services.

Topics discussed:

Links:

", + "Episodes Title": "Node.js at Netflix with Yunong Xiao", + "Episodes Uid": "SED3527907829", + "Episodes Audio File": "c4f21e6128e71d7271699a708f94fd26.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "gh", + "Episodes ID": "33e68f30-e329-11ea-91a2-dfab30e19534", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/phil_haack2.mp3", + "Episodes Pubdate Date": "2015-09-08", + "Episodes Summary": "

Phil Haack is a former PM on Microsoft’s ASP.NET MVC Framework, as well as NuGet, an open-source package manager. He currently works on Github Desktop at Github.

", + "Episodes Title": "Microsoft Open-Source with Phil Haack", + "Episodes Uid": "SED7599796697", + "Episodes Audio File": "f1f5aa91f526753716aff5492dbf6299.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ku", + "Episodes ID": "f3fbd8ee-e328-11ea-91a2-6f7478df6868", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_12_MonopoliesandProofofStake.mp3", + "Episodes Pubdate Date": "2018-03-12", + "Episodes Summary": "

Decentralized applications might someday offer alternatives to modern monopolies. Uber, Airbnb, Facebook, Amazon—all of these services could be recreated on a decentralized stack of technologies like Ethereum, IPFS, and Golem. Fully decentralized services could be more transparent, cheaper, and more efficient.

But let’s be realistic. Today, even the simplest applications of fully decentralized blockchains don’t work as well as we need them to. Cryptokitties offered a glimpse into how a simple viral application can limit the throughput of Ethereum. And don’t forget that these technologies are in some ways still subject to centralization in their current form. Miners form the decentralized consensus layer—and that mining activity is physically centralized in large server farms.

The decentralized future is possible. In order to get there, we need to make progress on the low-level tools that such a world will be built upon. This is the realization that today’s guest Karl Floersh had. Karl is a researcher for the Ethereum Foundation. He was initially excited about the prospect of decentralized apps—such as a decentralized Uber. But as he looked more closely at the space, he realized how early we are, and how much work there is to be done on foundational technologies.

Proof of Stake is the central topic of discussion in today’s conversation with Karl. Proof of Stake is a consensus mechanism that is an alternative to Proof of Work. In Proof of Work, miners race to validate blocks of transactions. This results in duplicated effort and perhaps wasted energy. In Proof of Stake, validators are chosen to approve transactions. These validators lock up an amount of currency that they are willing to “stake.” If a validator acts badly, the validator will lose their entire stake.

This mechanism could be more efficient—and we will explain why that is in this episode. If Proof of Stake works, it could lead to a faster, truly decentralized Ethereum blockchain. That’s a remarkable potential outcome.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Monopolies and Proof of Stake with Karl Floersh", + "Episodes Uid": "SED8163450350", + "Episodes Audio File": "0a8672d08e5f80b24411c32676f42df8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "27y", + "Episodes ID": "133e54ac-e329-11ea-91a2-4b62951fcffb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/kafka_streams_edited.mp3", + "Episodes Pubdate Date": "2016-10-07", + "Episodes Summary": "

Kafka Streams is a library for building streaming applications that transform input Kafka topics into output Kafka topics. In a time when there are numerous streaming frameworks already out there, why do we need yet another? To quote today’s guest Jay Kreps “the gap we see Kafka Streams filling is less the analytics-focused domain these frameworks focus on and more building core applications and microservices that process data streams.”

Jay is the CEO of Confluent, a company that is building Kafka technology, and he is one of the original authors of Kafka. We began with a brief history of why Kafka evolved to be the message broker of choice for so many data engineering stacks, then we got into a discussion of streaming–what is streaming? How does Kafka communicate with streaming frameworks? Our conversation concluded with a discussion of Kafka Streams and the future of the Kafka data platform.

", + "Episodes Title": "Kafka Streams with Jay Kreps", + "Episodes Uid": "SED9838673171", + "Episodes Audio File": "9b6569a6a6dc687906fc30f2618f95fd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2fl", + "Episodes ID": "09ee7454-e329-11ea-91a2-3bdf88f41cb2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Unbabel_edited.mp3", + "Episodes Pubdate Date": "2017-01-25", + "Episodes Summary": "

Translation is a classic problem in computer science. How do you translate a sentence from one human language into another? This seems like a problem that computers are well-suited to solve. Languages follow well-defined rules, we have lots of sample data to train our machine learning models.

And yet, the problem has not been solved–largely because languages don’t always follow rules. We have idioms and subtle contextual clues that make it hard to provide a computer with hard and fast rules for translation.

Unbabel is a company whose solution to translation puts a human in the loop to correct the error-prone translations that computers often make. In this episode, Vasco Pedro joins the show to explain Unbabel’s approach to translation, its technology stack, and the business applications for translation.

", + "Episodes Title": "Translation with Vasco Pedro", + "Episodes Uid": "SED2062060754", + "Episodes Audio File": "75aacc9f4817de2a5fd4f78c5cdf9857.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5oz", + "Episodes ID": "ee1c9936-e328-11ea-91a2-e700fcdf3b29", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_13_FBPeteHunt.mp3", + "Episodes Pubdate Date": "2019-05-13", + "Episodes Summary": "

Facebook engineering is commonly described by two words: move fast.

Building products quickly has been a differentiating characteristic of the company since its inception. From the longtime engineers to the summer interns, Facebook instills a sense of immediacy and opportunity in all of its employees.

The goal of Facebook is to make the world more open and transparent, with the intention of creating greater understanding and connection through Internet services. More than any other company in history, Facebook has enabled people to communicate with each other via simple user interfaces and real, authenticated human identity.

Facebook must move fast, because the vision for Facebook is without precedent. It may feel like the Facebook mission is already finished, because you can already use Facebook to connect with anyone across the world with an Internet connection.

But once you are connected to somebody on Facebook, there are only a small number of interactions you can take: sending a message, sharing a photo, broadcasting a video stream. There are so many more parts of our lives waiting to be digitized, and many of these require a real identity system to work properly.

More than any other company, Facebook is positioned to expand our system of real-world human trust onto the Internet. The depth and breadth of the engineering problems required to accomplish this demands that Facebook move fast. To move slower would cause all of us to pay the opportunity cost of having to wait longer to interconnect our global society.

Pete Hunt worked as an engineer at Facebook for three and a half years. At Facebook, he helped build React, a set of technologies that have significantly improved frontend application interface development. After the Instagram acquisition, Pete was the first engineer from Facebook to join the Instagram team to help bring the two companies together.

Pete left Facebook in 2014 to start Smyte, a company that made trust and safety tools for marketplaces and social networks. Smyte was acquired by Twitter, where Pete now works on engineering problems relating to trust, safety, health, and infrastructure.

Pete joins the show for the first of several episodes with Facebook engineers. In these episodes, we will explore the engineering practices of Facebook–from scaling Facebook’s PHP monolith to open sourcing React and GraphQL. Other topics will include management, onboarding, and product strategy.

Our goal is to present a holistic picture of how Facebook engineering works, so that other organizations can learn to adopt practices that will allow them to move faster. We hope you enjoy this series on Facebook engineering.

RECENT UPDATES:

The FindCollabs Open has started. It is our second FindCollabs hackathon, and we are giving away $2500 in prizes. The prizes will be awarded in categories such as machine learning, business plan, music, visual art, and JavaScript. If one of those areas sounds interesting to you, check out findcollabs.com/open!

The FindCollabs Podcast is out!

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

", + "Episodes Title": "Facebook Engineering with Pete Hunt", + "Episodes Uid": "SED3275752652", + "Episodes Audio File": "5499f2e90a151180b0e886c82014cbf7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3zd", + "Episodes ID": "f2b426f8-e328-11ea-91a2-e318d0329491", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_11_BitcoinLightningNetwork.mp3", + "Episodes Pubdate Date": "2018-06-11", + "Episodes Summary": "

Big blocks or small blocks: this is the fundamental question of Bitcoin scalability.

The argument for big blocks is also known as “on-chain scalability.” Under this strategy, each block in the append-only chain of Bitcoin transaction blocks would grow in size to be able to support lower transaction fees and higher on-chain throughput. A set of Bitcoin users who supported this idea forked Bitcoin to create Bitcoin Cash, a version of Bitcoin that has a larger block size.

The argument for small blocks asserts that scaling Bitcoin does not require a larger block size. Under this model, the scaling demands of the Bitcoin blockchain would be handled by sidechains. A sidechain is a network of person-to-person payment channels that only reconcile with the Bitcoin blockchain to checkpoint batches of transactions. These sidechains can be connected together to form the “lightning network.”

Lightning network is hard to implement. To implement a lightning network requires solving real-world distributed systems problems that are unprecedented. It’s much more complicated than deploying a blockchain with a larger block size.

In addition, opponents of lightning network suggest that this will lead to a centralized banking system being constructed on top of Bitcoin.

Opponents of lightning network fear that instead of a decentralized payments network, the world with lightning network will be a lower cost version of the present financial system, in which JP Morgan and Blockstream partner up to battle Coinbase in a centralized war for control of the unbanked.

These big blockers argue that the new banks on the lightning network will be just like the old banks–censorious of transactions and held in the domineering palms of the global financial kleptocracy.

So why bother with the lightning network approach? Why are we building this inelegant, kludgey system of off-chain, potentially centralized banking 2.0 complexity? Why not just increase the block size indefinitely and keep things simple? And even if we increased the block size today, couldn’t we still deploy lightning network in the future while appeasing the transaction volume of today?

One major reason is that growing the block size does have a cost. The bigger the block size, the more demands it places on any node that wants to maintain a record of those blocks. And if you grow the block size today, you forego the experiment of seeing whether a small block size plus lightning network could in itself handle the transaction volume of a global financial system.

The framing of “big blockers versus small blockers” is a conveniently polarized reduction of a much more granular reality. To believe that there is no subtlety between the two sides of this debate is to underestimate the number of dimensions to this argument. It’s an unfortunate side effect of rigidly programmed Twitter bots, and a political atmosphere in which your lines in the sand are demarcated by which subreddit you choose to affiliate with.

That said–my impression is that the more experienced engineers are overwhelmingly on the side of small blocks plus lightning network as the most promising approach to scaling Bitcoin. Take whatever side of the debate you want. A single line of Bitcoin core code speaks much louder than an avalanche of tweets.

In today’s episode, Jameson Lopp joins the show to explain why lightning network is an appealing engineering construct. We play the devil’s advocate and contrast lightning network with a big block approach, as well as a big block plus lightning network approach. Jameson also describes his experience working within the Ethereum ecosystem, and gives a sober explanation of some of the issues that Ethereum scalers may themselves encounter.

", + "Episodes Title": "Bitcoin Lightning Network with Jameson Lopp", + "Episodes Uid": "SED9890958858", + "Episodes Audio File": "721d56ef40fcb348302b4255747ea217.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3an", + "Episodes ID": "f54eacee-e328-11ea-91a2-dfb02e0835cc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CRDTs_Decentralized_Files.mp3", + "Episodes Pubdate Date": "2017-12-08", + "Episodes Summary": "

The Internet was designed as a decentralized system.

Theoretically, if Alice wants to send an email to Bob, she can set up an email client on her computer and send that email to Bob’s email server on his computer. In reality, very few people run their own email servers. We all send our emails to centralized services like Gmail, and connect to those centralized services using our own client—a browser on our laptop or a mobile application on our smart phone.

Gmail is popular because nobody wants to run their own email server—it’s too much work. With Gmail, our emails our centralized, but centralization comes with convenience.

Similar centralization happened with online payments.

If Alice wants to send $5 to Bob, she needs to go through centralized banking infrastructure. Alice tells her bank to send $5 from her bank account to Bob’s bank account. This is not how it works in the physical world. if Alice wants to pay cash to Bob, she doesn’t have to go and meet him at a physical bank. She just takes out a $5 bill from her wallet and hands it to him.

The invention of Bitcoin proved that digital wallets and peer-to-peer payments are possible. But running your own wallet is like running your own email server. It is inconvenient, and so we trade decentralization for convenience once again. We use services like Coinbase, where users buy and sell cryptocurrencies in a centralized provider.

There are people in the cryptocurrency community who hate the idea of Coinbase. These people keep their cryptocurrency spread out on their own hardware wallets. Some of these people also run their own email servers.

Are these people just adding unnecessary inconvenience to their lives for no reason? No. These are smart, successful people. They don’t like to waste time. So what are they doing running their own email servers?

Distributed systems theory teaches the risk of centralized computer systems. If you have a single server that all your communication has to be routed through, your computer network will stop functioning if that server dies.

Today, civilization is reliant on centralized computer systems. This is fundamentally dangerous. The 2008 financial crisis proved how risky it is to centralize our money in the hands of a few people. The Equifax breach proved how risky it is to centralize our identity in the hands of a few people.

What happens if Dropbox runs out of money and has to shut down? What happens if all of the data centers at Amazon Web Services get wiped simultaneously? What happens if Coinbase gets hacked and every user at Coinbase loses all their money?

We have seen centralized systems collapse. The people who are running their own email servers are not crazy. Even if Gmail disappears tomorrow, they will still have access to their emails. With the example of email, we see that deploying and managing a decentralized system is possible.

Decentralization is a desirable feature of computer systems. So how do we make more of our applications decentralized?

The cypherpunks were working for decades to make decentralized money a reality. Satoshi Nakamoto invented the blockchain, and we now have a computer science construct that enables decentralized money. The blockchain also enables many other decentralized applications.

By solving a specific problem, Satoshi came up with a general solution. This is how progress often happens in computer science. In order to fix a system, we create a new tool. That tool can be applied to other systems that we don’t anticipate.

The blockchain is a tool that solves one set of problems in distributed systems. Conflict-free replicated data types are another type of tool.

Conflict-free replicated data types (or CRDTs for short) are objects that can be mutated by multiple users at the same time without creating data corruption. The most common example of a conflict-free replicated data type is the shopping cart.

Let’s say Alice and Bob share an account on an ecommerce web site. Alice is building a house, and she wants to buy some tools online. Alice has a shopping cart with a hammer in it. Bob logs into the ecommerce web site from a different computer at the same time Alice is logged in. Bob just wants to buy a tuxedo—he doesn’t know why Alice left a hammer in the shopping cart, so he clicks a button to remove all the items from the shopping cart. At the exact same moment, Alice clicks from her computer to add a drill to the shopping cart.

The server receives both requests: Bob wants to delete all items in the shopping cart, Alice wants to add a drill to the shopping cart. Both requests occurred at the exact same time, but we have to decide how to process them in some order. This is a situation known as a conflict.

Which request should execute first? Should the resulting shopping cart be empty? Should the shopping cart only have a drill in it? In either case, Alice or Bob is going to be disappointed—there is no way to avoid that. But we need some way to resolve the conflict deterministically. We do not want to have to send a message to both Alice and Bob that says “sorry, our shopping cart cannot handle your request. Please try again later.”

We need the shopping cart to be a conflict-free shopping cart—and today’s episode is about the different techniques that can be used for conflict resolution.

The shopping cart is a simple example where user collaboration leads to conflicts. Imagine all the other ways you collaborate with other users: chat systems like Slack, social networks like Facebook, document systems like Google Docs.

One way to resolve a conflict is through a technique called operational transform. Operational transform requires all the operations in the distributed system to be funneled through a centralized server. When a conflict occurs, the centralized server detects the problem and figures out how to resolve it.

Google Docs uses operational transform to resolve the frequent conflicts that occur when two users are sharing a text document. But operational transform only works if you have a centralized server.

An alternative solution is conflict-free replicated data types, which maintain each user’s replica of the data in a format that allows the client copies to resolve conflicts in a peer-to-peer fashion—without a centralized server.

Last example: Alice and Bob are now collaborating on a document that uses a CRDT data structure under the hood. Whenever they send their local changes to each other, any conflicts that occur can be resolved directly on the client. Alice and Bob can collaborate on a document just like they can send emails to each other.

With CRDTs, we can build decentralized, collaborative applications. But CRDTs are hard to use. Just like with blockchain technology, we don’t yet have the simple, elegant abstractions that let inexperienced programmers build peer-to-peer applications without the fear of conflicts.

Martin Kleppman is a distributed systems researcher and the author of Data Intensive Applications. Martin is concerned by the centralization of our computer networks, and he works on CRDT technology in order to make it easier for people to build peer-to-peer applications.

Most of the people who know how to build systems with CRDTs are distributed systems PhDs, database experts, and people working at huge internet companies. How do you make developer-friendly CRDTs? How do you allow random hackers to build peer-to-peer applications that avoid conflicts? Start by making a CRDT out of the most widely used, generalizable data structure in modern application development: the JSON object.

In today’s episode, Martin and I talk about conflict resolution, CRDTs, and decentralized applications. This is Martin’s second time on the show, and his first interview is the most popular episode to date. You can find a link to that episode in the show notes for this episode, or you can find it in the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Decentralized Objects with Martin Kleppman", + "Episodes Uid": "SED2033937343", + "Episodes Audio File": "3650448aaef83113d920e24f8d410e14.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "35q", + "Episodes ID": "f5f2510a-e328-11ea-91a2-df2657271d66", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Keybase.mp3", + "Episodes Pubdate Date": "2017-10-24", + "Episodes Summary": "

Public key encryption allows for encrypted, private messages. A message sent from Bob to Alice gets encrypted using Alice’s public key. Public key encryption also allows for signed messages–so that when Alice signs a message, Alice uses her private key and Bob can verify it if Bob has her public key.

In both cases, Bob needs Alice’s public key! If Bob gets that public key from an email message, Bob is trusting that the email message is secure–and if Bob can’t ever verify that first message containing the key, he has no way to verify the messages that come after it.

This is the problem of key distribution.

Key distribution undermines the usability of PGP encryption. Serious encryption advocates will sometimes meet in person to exchange pieces of paper containing public keys. Keybase is a company that attempts to solve the problem of key distribution by having users connect social media accounts and devices to Keybase, in order to collectively verify who you are, and then give you the power to share your public key.

Max Krohn is a founder of Keybase, and was previously a founder of SparkNotes and OKCupid. Max was on the show a few years ago to discuss the basics of Keybase, and in this episode he explores some of the abstractions that Keybase has built on top of its core identity tool–Keybase File System, Keybase Teams, and Keybase Git. We do break down the basics of Keybase, but if you want a more thorough explanation, you might like to check out that older episode, you can download the Software Engineering Daily app on iOS or Android to find all of our old episodes.

", + "Episodes Title": "Keybase with Max Krohn", + "Episodes Uid": "SED1538819458", + "Episodes Audio File": "6174812b685149899ec907e1d1ce0d6b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3k7", + "Episodes ID": "f40a1788-e328-11ea-91a2-6fb2bcc0034b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_07_SmartContracts.mp3", + "Episodes Pubdate Date": "2018-03-07", + "Episodes Summary": "

Smart contracts are programs that run on the Ethereum blockchain. A smart contract developer pays Ether to deploy the contract. When a contract is deployed, every full node on the Ethereum blockchain has a copy of the contract code in that node’s address space.

Every full node needs to hold a copy of every smart contract. This allows every full node to process every call to any smart contract. If you want to call a smart contract, that contract will execute on every full node.

When you call a smart contract, you are initiating a transaction. Like Bitcoin transactions, these Ethereum transactions get batched into blocks. Ethereum full nodes compete to solve the cryptographic puzzle associated with a block. But instead of mere financial transactions, these are computational transactions.

Raine Revere is a smart contract engineer and cofounder at Maiden and she joins the show to describe smart contract creation and deployment. It’s a great introduction to some Ethereum fundamentals.

To find all of our old episodes about cryptocurrencies, check out our apps in the  iOS or Android app store. They have all 700 of our episodes, with recommendations, related links, discussions and more. And it’s all open source–if you are looking for an open source project to contribute to, come check us out at github.com/softwareengineeringdaily. We welcome all kinds of contributors–new developers and experts. Engineers and non-technical people.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Smart Contracts with Raine Revere", + "Episodes Uid": "SED5665676760", + "Episodes Audio File": "efdf2b510613b5a44bef819f9fa3641d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ih", + "Episodes ID": "0567cdfe-e329-11ea-91a2-ef3902a8d451", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CloudbleedwithHaseeb.mp3", + "Episodes Pubdate Date": "2017-03-04", + "Episodes Summary": "

Thursday February 23rd was a big day in security news: details were published about the Cloudbleed bug, which leaked tons of plaintext requests from across the Internet into plain view. On the same day, the first collision attack against SHA-1 was demonstrated by researchers at Google, foretelling the demise of SHA-1 as a safe hashing function.

What does this mean for the average engineer? What are the implications for regular internet users? Haseeb Qureshi interviews Max Burkhardt, a security researcher at Airbnb, to get to the bottom of what exactly happened, what it means, and how it affects the security of web applications.

", + "Episodes Title": "Cloudbleed and SHA-1 Collision with Max Burkhardt", + "Episodes Uid": "SED4570472070", + "Episodes Audio File": "22a18b9f3fc1f198a9a54e6e13141066.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2m6", + "Episodes ID": "ff34e304-e328-11ea-91a2-6bbf7145b2a6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/twentyone_edited.mp3", + "Episodes Pubdate Date": "2017-04-21", + "Episodes Summary": "

Bitcoin is underappreciated even to this day. The public focus is usually on the speculative value, but Bitcoin has functional value as a technology platform.

If I want to make 100 transactions with my bank for 1 cent, the bank won’t allow it. Our current financial infrastructure is not set up for micropayments. Bitcoin is built with micropayments in mind. As Bitcoin works through its governance issues and its scalability problems, we will see gradual improvement in financial liquidity between people and machines.

21 is a company that has raised $120M to make Bitcoin useful to developers. This is a long term project, and the first step of that project is to get Bitcoin in the hands of users. To fulfill that end, 21 is developing services that encourage people to make small digital transactions.

The first service is the 21 messaging service, where users can pay to send messages to people who are unlikely to respond to an unsolicited email otherwise. For example, if I want to send an email to a venture capitalist pitching my company, I am more likely to get a response if I pay that venture capitalist $20 to read my message through 21, rather than if I sent a cold email from my email address.

Balaji Srinivasan is the CEO of 21, and he joins me for a conversation about the potential of Bitcoin and the objectives of the company he is building.

Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

", + "Episodes Title": "21 with Balaji Srinivasan", + "Episodes Uid": "SED9363298088", + "Episodes Audio File": "7adb54e922629ddb57fe4300d936830b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3iu", + "Episodes ID": "f4376cb0-e328-11ea-91a2-a7628570ecff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_22_MicrosoftServerless.mp3", + "Episodes Pubdate Date": "2018-02-22", + "Episodes Summary": "

On Software Engineering Daily, we have been covering the “serverless” movement in detail. For people who don’t use serverless functions, it seems like a niche. Serverless functions are stateless, auto-scaling, event driven blobs of code. You might say “serverless sounds kind of cool, but why don’t I just use a server? It’s a paradigm I’m used to.”

Serverless is exciting not because of what it adds but because of what it subtracts. The potential of serverless technology is to someday not have to worry about scalability at all.

Today, we take for granted that if you start a new company, you are building it on cloud infrastructure. The problem of maintaining server hardware disappeared for 99% of startups, which unlocked a wealth of innovation.

The cloud also simplified scalability for most startups–but there are still plenty of companies that struggle to scale. Significant mental energy is spent on the following questions: How many database replicas do I need? How do I configure my load balancer? How many nodes should I put in my Kafka cluster?

Serverless functions are important because they are an auto-scaling component that sits at a low level. This makes it easy to build auto scaling systems on top of them. Auto scaling databases, queueing systems, machine learning tools, and user applications.

And since the problem is being solved at such a low level, the pricing competitions will also take place at the low level, meaning that systems built on serverless functions will probably see steep declines in costs in the coming years. Serverless compute could eventually become free or nearly free, with the major cloud providers using it as a loss leader to onboard developers to higher level services.

All of this makes for an exciting topic of discussion, that we will be repeatedly covering. Today’s show is with Eduardo Laureano, the principal program manager of Azure Functions. It was a fantastic conversation and we covered applications of serverless, improvements to the “cold start problem,” and how the Azure Functions platform is built and operated. Full disclosure: Microsoft is a sponsor of Software Engineering Daily.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Summer internship applications to Software Engineering Daily are also being accepted. If you are interested in working with us on the Software Engineering Daily open source project full-time this Summer, send an application to internships@softwareengineeringdaily.com. We’d love to hear from you.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless Systems with Eduardo Laureano", + "Episodes Uid": "SED9284465482", + "Episodes Audio File": "468eb6a6ebf926255ac91501ae6aec2b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ns", + "Episodes ID": "ee402e96-e328-11ea-91a2-37b821b1093b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_02_ContrastSecurity.mp3", + "Episodes Pubdate Date": "2019-05-02", + "Episodes Summary": "

The modern software supply chain contains many different points of distribution: JavaScript frameworks, npm modules, Docker containers, open source repositories, cloud providers, on-prem firmware, IoT, networking proxies, and so much more.

With so much attack surface, securing a large enterprise is an uphill battle. Jeff Williams is the CTO at Contrast Security, a company that makes infrastructure monitoring tools. Contrast Security works by intercepting network traffic at a low level and assessing whether that traffic maps to a common threat model.

Jeff joins the show to talk about different approaches to monitoring and securing large infrastructure deployments.

Contrast Community Edition

RECENT UPDATES:

FindCollabs is a company I started recently

The FindCollabs Podcast is out!

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

We are booking sponsorships for Q3, find more details at https://softwareengineeringdaily.com/sponsor/

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

", + "Episodes Title": "Security Monitoring with Jeff Williams", + "Episodes Uid": "SED9602212402", + "Episodes Audio File": "6ea5f28c63e1bac89fabac0ff86fa783.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4u1", + "Episodes ID": "f0c13156-e328-11ea-91a2-231de66bffb3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_30_SalesML.mp3", + "Episodes Pubdate Date": "2018-10-30", + "Episodes Summary": "

David Cancel has started five companies, most recently Drift. Drift is a conversational marketing and sales platform. David has a depth of engineering skills and a breadth of business experience that make him an amazing source of knowledge. In today’s episode, David discusses topics ranging from the technical details of making a machine learning-driven sales platform to the battle scars from his early career, when he spent a lot of time building products that people did not want. He has found success by focusing on building software that the market has shown a desire for.

Chatbots were a popular, trendy subject a few years ago. The success of chatbots manifested in them fading into the background, and becoming a subtle, increasing part of our everyday interactions. Not every online interaction can be replaced by a chatbot, but many online interactions can be made more efficient by using chatbots. Chatbots can serve well-defined information, like product features, or the hours of operation of a business. When a chatbot gets a question that it cannot answer, the bot can route the conversation to a human.

When a customer lands on a web page of a company using Drift, they see a chat box appear in the corner of the screen. The customer is able to communicate through that chat box with a bot that represents the company. The customer can learn about the product, schedule a call with a salesperson, and get other useful utilities from the Drift sales bot.

The Drift chatbot messaging system is handled by Elixir/Erlang. Erlang is widely known as the messaging language that was used to scale WhatsApp while maintaining high availability. On the backend, Java services take the interactions from the Driftbot and pull it into a CRM, which allows sales and marketing people to manage information about the customers that are interacting with the chatbot. David gives lots more detail around the engineering stack, the deployment model, and his thoughts on the business and modern engineering.

We recently launched a new podcast: Fintech Daily! Fintech Daily is about payments, cryptocurrencies, trading, and the intersection between finance and technology. You can find it on fintechdaily.co or Apple and Google podcasts. We are looking for other hosts who want to participate. If you are interested in becoming a host, send us an email: host@fintechdaily.co

", + "Episodes Title": "Drift: Sales Bot Engineering with David Cancel", + "Episodes Uid": "SED8684753134", + "Episodes Audio File": "7ebde0a5f6843066479eb0d9c247dbec.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "52u", + "Episodes ID": "f03b1972-e328-11ea-91a2-1f05a36e34ae", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_10_ServerlessResearch.mp3", + "Episodes Pubdate Date": "2018-12-10", + "Episodes Summary": "

The Berkeley AMPLab was a research lab where Apache Spark and Apache Mesos were both created. In the last five years, the Mesos and Spark projects have changed the way infrastructure is managed and improved the tools for data science.

Because of its proximity to Silicon Valley, Berkeley has become a university where fundamental research is blended with a sense of industry applications. Students and professors move between business and academia, finding problems in industry and bringing them into the lab where they can be studied without the day-to-day pressures of a corporation.

This makes Berkeley the perfect place for research around “serverless”.

Serverless computing abstracts away the notion of a server, allowing developers to work at a higher level and be less concerned about the problems inherent in servers–such as failing instances and unpredictable network connections.

With serverless functions-as-a-service, the cloud provider makes guarantees around the execution of serverless code–such as with AWS Lambda. With serverless backend services, the cloud provider makes guarantees around the reliability of a database or queueing system.

The cloud provider is operating servers to power this functionality. But the user is not exposed to those servers.

Today’s show centers around the serverless functions-as-a-service. This is a new paradigm of computing, and there are many open questions. How can the servers for our functions be quickly provisioned? How can we parallelize batch jobs into functions as a service? How can large numbers of serverless functions communicate with each other reliably to coordinate?

In production applications, functions-as-a-service are mostly used for “event-driven” applications. But the potential for functions-as-a-service is much larger.

Ion Stoica is a professor of computer science at Berkeley, where he leads the RISELab. He is the co-founder of Conviva Networks and Databricks. Databricks is the company that was born as a result of the research on Apache Spark. Ion now serves as executive chairman of Databricks. Ion joins the show to describe why serverless computing is exciting, the open research problems, and the solutions that researchers at the RISELab are exploring.

", + "Episodes Title": "Serverless Research with Ion Stoica", + "Episodes Uid": "SED9566077917", + "Episodes Audio File": "1642d52d20a52338619018c9d53abfe0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "44y", + "Episodes ID": "f2591e20-e328-11ea-91a2-cf63aa10ba4d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_06_TimOReilly.mp3", + "Episodes Pubdate Date": "2018-07-06", + "Episodes Summary": "

Tim O’Reilly’s book What’s the Future? is an overview of business, technology, and society. As the founder of O’Reilly Media, Tim has been steeped in technology trends for the last 40 years. From his vantage point running conferences and publishing technical content, Tim has been able to make informed predictions about what is coming next.

In today’s conversation, Tim gave his perspective on how artificial intelligence will impact our world in the coming decades. More importantly–Tim emphasizes the role of human agency. The future is not something that merely happens to us as we sit back and eat popcorn. Today, we make decisions, and those decisions that we make could help lead us to technology utopia or towards the fall of our great technological empire.

On the subject of business, Tim gave a radically different perspective than most of the entrepreneurs that come on Software Engineering Daily. In our conversation, he raised the question of why entrepreneurs raise massive amounts of money, get on the treadmill of startup hype, and build a company around negative cash flows. For that model, the only possible outcomes are going public, being acquired, or flaming out completely. O’Reilly Media has been cash flow positive since the beginning, and the company has steadily compounded, growing successively bigger businesses from publishing to conferences to online learning.

This episode gave me a lot to think about–just as the O’Reilly Conferences have throughout the years. O’Reilly Media has graciously partnered with SE Daily since we were very small, so I have great admiration for the company and Tim himself. It was a pleasure to get the chance to meet him in person.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Future Projection with Tim O’Reilly", + "Episodes Uid": "SED8178063817", + "Episodes Audio File": "3804d8dc0a585c3630073431c20077a5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "64f", + "Episodes ID": "ec911240-e328-11ea-91a2-ef32073a34cb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_30_FacebookParseAcquisitionwithIlyaSukhar.mp3", + "Episodes Pubdate Date": "2019-08-30", + "Episodes Summary": "

Ilya Sukhar founded Parse in 2011 to make cloud services for mobile developers. Parse was a newer kind of cloud provider called “backend-as-a-service”, built to simplify the complexities of Amazon Web Services and the complexities of the mobile ecosystem. 

During this time, Facebook was in the middle of its shift toward becoming a mobile application company. Ads on the smartphone were not yet a proven business model. Facebook was exploring other business lines, and decided to purchase Parse for $85 million, with the intention of building a cloud developer platform.

Shortly after the acquisition, Facebook’s mobile ads business started to see considerable success. With the mobile ads business finding traction, Facebook shifted all available resources towards supporting that business model. In 2017, Parse was shut down.

Ilya joins the show to give his experience starting Parse, selling the company to Facebook, and then seeing the company he had built get shut down as it became an unfortunate casualty of Facebook’s advertising success. We talked a lot about the experience of building a backend-as-a-service company, as well as what makes Facebook special as an organization, and how the success of Facebook’s mobile business happened to coincide with the Parse acquisition.

", + "Episodes Title": "Facebook Parse Acquisition (Part 2) with Ilya Sukhar", + "Episodes Uid": "SED4119418861", + "Episodes Audio File": "0e58baa2877946b74989f05fcc527dae.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4bn", + "Episodes ID": "f1a62e96-e328-11ea-91a2-73d1a2182483", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_21_BuildFasterNader.mp3", + "Episodes Pubdate Date": "2018-08-21", + "Episodes Summary": "

Building software today is much faster than it was just a few years ago. The tools are higher level, and abstract away tasks that would have required months of development. Much of a developer’s time used to be spent optimizing databases, load balancers, and queueing systems in order to be able to handle the load created by thousands of users. Today, scalability is built into much of our infrastructure by default.

We have had several years of infrastructure with automatic scalability, and some of the more recent advances in developer tooling are about convenience, and faster development time. Developers are spending less time dealing with the ambiguous idea of a “server” and more time interacting with well-defined APIs and data sources.

A few examples are AppSync from Amazon Web Services and Firebase from Google. These tools are like databases with rich interactive functionality. Instead of having to create a server to listen to a database for changes and push notifications to users in response to those changes, AppSync and Firebase can be programmed to have this kind of functionality built in.

There are many other examples of high level APIs, rich backends, and developer productivity tools that lead to shorter development time. What does this mean for developers? It means we can build much faster. We can prototype quickly for low amounts of money–without sacrificing quality. We can spend more time focusing on design, user experience, and business models and less time focusing on keeping the application up and running.

Nader Dabit is a developer advocate at Amazon Web Services, and he returns to the show to discuss modern tooling, and how that tooling changes the potential for high output and fast iteration among developers. It is a strategic, philosophical discussion of how to build modern software.

", + "Episodes Title": "Build Faster with Nader Dabit", + "Episodes Uid": "SED4830875749", + "Episodes Audio File": "0e25a261687addd5e68810fbddb8e746.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "47g", + "Episodes ID": "f2273540-e328-11ea-91a2-47e0f81637ef", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_20_WebAssembly.mp3", + "Episodes Pubdate Date": "2018-07-20", + "Episodes Summary": "

JavaScript has been the exclusive language of the web browser for the last 20 years. Whether you use Chrome, Firefox, Internet Explorer, or Safari, your browser interprets and executes code in a virtual machine–and that virtual machine only runs JavaScript. Unfortunately, JavaScript is not ideal for every task we want to perform in the browser.

Think about the use cases where you need to use software outside of the browser: video editing, music production, 3D art, video games. These applications require a high degree of performance that is hard to get from raw JavaScript.

WebAssembly was created to get better performance on the web. WebAssembly allows code from other languages to be compiled and run in the browser. With WebAssembly, languages such as C, C++, and Rust can be used to achieve major performance gains. WebAssembly is still under development, and eventually more programming languages will be accessible as well.

Lin Clark is an engineer on the Mozilla Developer Relations team, and has been working closely on the WebAssembly project. She is the author of a detailed series of illustrated blog posts that explain how WebAssembly works. In this episode, we discuss how WebAssembly came to be, its advantages over a web driven purely by Javascript, what is possible with WebAssembly, and its engineering implementation.

", + "Episodes Title": "WebAssembly with Lin Clark", + "Episodes Uid": "SED2424078390", + "Episodes Audio File": "8574623ebb9cae0f1aaede443fea396a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "29l", + "Episodes ID": "11a6ce26-e329-11ea-91a2-bfd830197581", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/indiehackers_edited.mp3", + "Episodes Pubdate Date": "2016-11-04", + "Episodes Summary": "

Indie Hackers is a website that profiles independent developers who have made profitable software projects, usually without raising any money. These projects make anywhere from a few hundred dollars a month to more than $100,000 as in the case with park.io, one of the services profiled by Indie Hackers.

Courtland Allen is the creator, engineer, and interviewer behind Indie Hackers. For each business that is profiled by Indie Hackers, Courtland conducts a short interview with the founder.

Courtland joins the show to discuss the changing trends that are making it easier to bootstrap a software business if you are a capable developer–or even if you are a nontechnical person who understands how software works. Since Courtland and I are both in the business of interviewing engineers, we had a lot to talk about, and this is a fantastic episode.

", + "Episodes Title": "Indie Hackers with Courtland Allen", + "Episodes Uid": "SED4486092988", + "Episodes Audio File": "d6e72382e99b4e7c583a5f2e7760756d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jj", + "Episodes ID": "03721b80-e329-11ea-91a2-e39edf6d26a3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/NetNeutrality.mp3", + "Episodes Pubdate Date": "2017-03-24", + "Episodes Summary": "

Net neutrality is the principle that internet service providers and governments regulating the internet should treat all data on the internet the same. Debates around Net Neutrality can be as contentious as subjects like global warming, or tabs vs. spaces.

To a hardcore free market economist, Net Neutrality sounds suspicious. Why would it be good for the government to regulate prices on the data that passes around wires owned by a corporation? The problem is that a large portion of the United States can only be served by wires owned by a single company. In those instances, the company that owns the wires has monopoly pricing power over the data delivered to homes in those geographic regions.

Quincy Larson is the founder of Free Code Camp and a frequent author of internet-based articles on Medium. He returns to Software Engineering Daily to make the case for Net Neutrality. I was convinced by some of his arguments and less convinced by others. In any case, I think you will find this episode entertaining and informative.

If you are like me, after this episode you will have at least a slightly better understanding of the issues surrounding Net Neutrality.

Inside the Invisible War for the Open Internet

", + "Episodes Title": "Net Neutrality with Quincy Larson", + "Episodes Uid": "SED4182547574", + "Episodes Audio File": "83c5a9a88d9273070480264aaac6d72a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ww", + "Episodes ID": "f730970c-e328-11ea-91a2-4fb405992a81", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ReinforcementLearning.mp3", + "Episodes Pubdate Date": "2017-07-21", + "Episodes Summary": "

Reinforcement learning is a type of machine learning where a program learns how to take actions in an environment based on how that program has been rewarded for actions it took in the past. When program takes an action, and it receives a reward for that action, it is likely to take that action again in the future because it was positively reinforced.

Michal Kempka is a computer scientist work works on VizDoom, an AI research platform for reinforcement learning, with co-creators Marek Wydmuch, Grzegorz Runc, Jakub Toczek, Wojciech Jaśkowski. VizDoom is based on the first-person dungeon game Doom. In VizDoom, an autonomous agent navigates through a maze avoiding enemies.

Reinforcement learning is a widely used tool for machine learning, and we will be doing more shows in the future that explain how it works in further detail.

Cornell University Library: VizDoom

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Reinforcement Learning with Michal Kempa", + "Episodes Uid": "SED8885317502", + "Episodes Audio File": "593e3b5c0f4efcb705e029007a7e1706.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7c4", + "Episodes ID": "e8e61406-e328-11ea-91a2-d75b5656c42d", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2019_06_13_Railyard_adfree.mp3", + "Episodes Pubdate Date": "2020-06-16", + "Episodes Summary": "

Originally published June 13, 2019. We are taking a few weeks off. We’ll be back soon with new episodes.

Machine learning allows software to improve as that software consumes more data.

Machine learning is a tool that every software engineer wants to be able to use. Because machine learning is so broadly applicable, software companies want to make the tools more accessible to the developers across the organization.

There are many steps that an engineer must go through to use machine learning, and each additional step inhibits the chances that the engineer will actually get their model into production.

An engineer who wants to build machine learning into their application needs access to data sets. They need to join those data sets, and load them into a machine (or multiple machines) where their model can be trained. Once the model is trained, the model needs to test on additional data to ensure quality. If the initial model quality is insufficient, the engineer might need to tweak the training parameters.

Once a model is accurate enough, the engineer needs to deploy that model. After deployment, the model might need to be updated with new data later on. If the model is processing sensitive or financially relevant data, a provenance process might be necessary to allow for an audit trail of decisions that have been made by the model.

Rob Story and Kelley Rivoire are engineers working on machine learning infrastructure at Stripe. After recognizing the difficulties that engineers faced in creating and deploying machine learning models, Stripe engineers built out Railyard, an API for machine learning workloads within the company.

Rob and Kelley join the show to discuss data engineering and machine learning at Stripe, and their work on Railyard.

", + "Episodes Title": "Stripe Machine Learning Infrastructure with Rob Story and Kelley Rivoire (Summer Break Repeat)", + "Episodes Uid": "SED5354795195", + "Episodes Audio File": "6c798b3e1ef69df0206173469be99976.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2fp", + "Episodes ID": "09ac484a-e329-11ea-91a2-c375ca35abba", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/kotlin_edited.mp3", + "Episodes Pubdate Date": "2017-01-26", + "Episodes Summary": "

Whatever engineering problem you have right now, the solution is probably not to write a new programming language. But sometimes it does make sense.

JetBrains makes IDEs–the interactive development environments that many people code in, like IntelliJ and Webstorm. And all of these IDEs are written in Java. So the JetBrains team is very familiar with Java and the JVM. Since JetBrains spends so much time working on tooling for developers, they also have an intimate understanding of the problems that developers encounter.

Kotlin was developed as an alternative to JVM languages such as Java and Scala. In this episode, Hadi Hariri from JetBrains explains why the company decided to build a new JVM language. We discuss many of its features, such as safety, concision, and its ability to compile to JavaScript.

Why Kotlin is My Next Programming Language: Ode to the Language You’ve Never Heard Of, by Mike Hearn

YouTube: GOTO 2016 Conference, Kotlin – Ready for Production, Hadi Hariri

", + "Episodes Title": "Kotlin with Hadi Hariri", + "Episodes Uid": "SED8392245348", + "Episodes Audio File": "913fa79f9159330b14ad30769f818b2c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3yb", + "Episodes ID": "f2b932c4-e328-11ea-91a2-0fc6783898c2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_08_InvestmentGames.mp3", + "Episodes Pubdate Date": "2018-06-08", + "Episodes Summary": "

Investing is an infinite game.

In a game, a player can formulate a strategy based on the available resources, the apparent variance of the environment, and the metagame of the other actors involved. For an investor, the game board includes companies, currencies, and people.

A successful game player can model their actions mathematically. They can describe a thesis for an in-game decision with clear language. Game players who reason through “gut feeling” do not perform well (unless their “gut” is aligned with correct mathematical heuristics). The same is true for investors. An investor who is going to be successful in the long term will be able to explain their investment thesis crisply.

Each investment represents a bet with net positive expected value. The expected value of an investment is the sum of all potential probability-weighted future outcomes of a business. Each of those potential expected outcomes is the anticipated outcome times the probability that the investment works out in the anticipated way.

Brian Singerman is a computer scientist and partner at Founder’s Fund. He is on the board of Affirm, AltSchool, Emerald Therapeutics, and a variety of other companies in disparate areas. He also plays lots of board games. Brian was a lot of fun to talk to because he was willing to field questions from an expansive range of topics–and he answered them so quickly and concisely that I started to get nervous that I was going to run out of things to ask him.

Many of the businesses Brian has invested in do not have a well-defined historical precedent. If a venture capital investor was trying to make bets in defined “sectors” that investor would probably overlook a business like Forward (a vertically integrated healthcare company) or Cloud9 (a collection of esports teams).

If an investment does not have a historical precedent, it’s harder to reason about it by analogy. You have to judge it by fundamental reasoning: the current market, the capability of the founders, and the economics of the business model.

In many professions, reasoning by analogy will work out perfectly fine. You can pattern match on the past, and use that to justify decisions for the future. But if your professional livelihood depends on reasoning by fundamental principles, you get trained to assess situations that do not have precedent.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Investment Games with Brian Singerman", + "Episodes Uid": "SED3879387654", + "Episodes Audio File": "b5baee0ced04c7c3a465c74cb0e928fd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5s2", + "Episodes ID": "eddcac18-e328-11ea-91a2-6bf88fa8ce87", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_05_31_ServiceMeshWars.mp3", + "Episodes Pubdate Date": "2019-05-31", + "Episodes Summary": "

A service mesh is an abstraction that provides traffic routing, policy management, and telemetry for a distributed application.

A service mesh consists of a data plane and a control plane. In the data plane, a proxy runs alongside each service, with every request from a service being routed through the proxy. In the control plane, an application owner can control the behavior of the proxies distributed throughout the application.

As the Kubernetes ecosystem has developed, the service mesh abstraction has become an increasingly desirable component of a “cloud native” application stack.

As companies enthusiastically adopt Kubernetes, they eventually find themselves with a large distributed system that is difficult to operate. A service mesh simplifies some of these operational difficulties, as we have explored in numerous previous episodes.

The Kubernetes community has grown to include lots of enterprises, and those enterprises want to adopt service mesh. But today, many of them are afraid to adopt the technology because there are multiple competing products, and it is unclear which one the community will centralize around–or if the community will end up supporting multiple products.

Over the next few weeks, we will be airing interviews from KubeCon EU 2019 in Barcelona. These interviews are a window into the world of the Kubernetes and the cloud-native ecosystem, which is transforming the world of infrastructure software.

The most prominent theme across these shows was that of service mesh. Why was service mesh such an important topic? Because the battle for service mesh supremacy is a classic technology competition between a giant incumbent and a startup with far fewer resources.

The Kubernetes ecosystem is beautifully engineered to allow for a marketplace of warring ideas where the most worthy competitor wins out–but in some cases there is room for multiple products to occupy different subsections of the market.

Across these episodes, one theme we will explore is the governance and the diplomacy of these competing solutions, and how the Kubernetes ecosystem is structured to allow for harmonious resolution to technology battles.

It is tempting to look at this competition between service meshes as winner-take-all. But as of late May 2019, we do not yet know if it will be winner-take-all. In order to predict how the service mesh wars will play out, the best we can do is to look at historical examples.

Container orchestration wars was a winner-take-all market. Container orchestration was a problem of such depth, such technical complexity and integration, that there had to be a single winner for the ecosystem to marshall around.

During the container orchestration wars, as Mesos and Docker Swarm and HashiCorp Nomad and Kubernetes fought for supremacy, many large enterprises made bets on container orchestration systems that were not Kubernetes. When the dust settled, Kubernetes was the victor, and these large enterprises who had adopted orchestration systems other than Kubernetes begrudgingly began thinking about how to migrate to Kubernetes.

But during the orchestration wars, many more enterprises were sitting out altogether. They did not choose Kubernetes or Mesos or Swarm. They chose to wait.

Enterprise technologists are smart, and they can tell when a technology is immature. Although many enterprises wanted an orchestration system to manage their Docker containers, they did not want to insert a heavy abstraction that they would have to tear out later on.

Once Kubernetes won the orchestration wars, enterprise dollars piled into the space. The cloud native community has grown faster than anyone expected, because we solved the collective action problem of centralizing on a container orchestrator.

From enterprises to cloud providers to ISVs to podcasters, we share the same vision for Kubernetes: it is the Linux for distributed systems.

Within the Kubernetes ecosystem, the thought leadership tries not to pick winners. It is better for everyone if the winners are decided through competition. In order to foster competition, interfaces into Kubernetes can provide a layer of standardization along which different products can compete. Enterprises can buy into an interface without buying into any particular product.

Examples include the container networking interface (CNI) and the container storage interface (CSI). Every Kubernetes application wants storage and networking, but these Kubernetes applications do not want to be locked into a particular provider. Since there is a standardized interface for networking and storage, these applications can swap out one storage provider for another, or one networking provider for another.

How does this relate to service mesh?

In the service mesh market, Buoyant was first to market with its open source project Linkerd. Today’s guest William Morgan is the CEO of Buoyant. Over the last four years, Linkerd has slowly grown a following of dedicated users who run the open source service mesh in production.

Over the last four years, Linkerd has changed from its initial technology of the embedded JVM service proxy developed at Twitter to a Rust-based sidecar data plane and a Go-based control plane. Buoyant’s dedicated focus to the service mesh space has won over much of the community, as was evidenced by Linkerd becoming the predominant apparel brand at Kubecon EU 2019: Linkerd hats and t-shirts were everywhere at the conference.

Why did Linkerd become trendy? Ironically, because of a competing service mesh whose launch strategy was widely seen as an affront to the spirit of the cloud native community.

Istio was created within Google, and launched with a set of brittle partnerships with IBM and other companies. Istio careened into the Kubernetes ecosystem with violent fanfare, trumpeting itself as the cloud native service mesh du jour through endless banner ads, marketing email campaigns, and KubeCon programming.

Any listener to this podcast knows I am as gullible as any technologist. I’m an idealist–and I wanted to believe that Istio represented the service mesh equivalent of Kubernetes. It’s from Google, it launched with a bunch of impressive logos, and it has an inspiring vision. Looks cloud native, smells cloud native, must be cloud native, right?

Unfortunately, Istio’s early marketing aggrandizements were disconnected from the nascent realities of the project. Istio was buggy and difficult to set up. Istio quickly developed a reputation as Google-manufactured vaporware: nice idea, not nearly ready for production.

For Linkerd, the timing could not have been better.

Istio’s romantic vision of an operating plane for routing traffic, managing security policy, and measuring network telemetry had seduced the enterprise masses. With their cravings unmet by Istio, these enterprises surveyed the market and quickly found their way to Linkerd, the humble service mesh next door, who had been waiting patiently all along.

The tide has turned against Istio, and towards Linkerd. But the service mesh wars have just begun. And as easy as it is to criticize Istio, the project is not only vaporware. Istio has a vision for a detailed operating plane that will evolve together with Envoy, a service proxy sidecar developed at Lyft.

Perhaps Istio’s early embers had too much marketing gasoline poured on them initially, but the project could still succeed. Google is the most sophisticated, well-resourced company in the world–and judging from Google’s adjacent strategic messaging around Anthos and other strategic initiatives, the company has already decided that Istio will be around for the long haul.

As a community, we should be grateful to witness the folly of Istio’s carpet-bomb marketing strategy. It is validation for the earnest resilience of the cloud native community, that even under the omnipresent duress of Google marketing, the community was able to collectively reject the Istio Kool Aid.

This should come as no surprise. The Cloud Native Computing Foundation resides within the Linux Foundation, and the Kubernetes ecosystem has been ordained with the ardent technical purity of Linus Torvalds.

The CNCF was formed under the looming shadow of AWS. The CNCF was seeded with the donation of Kubernetes by Google. Much like the Linux community was positioned as a rebellious movement in reaction to Microsoft’s dominance, the Kubernetes community represents a fervent desire to open up the market to cloud providers beyond the tight-lipped, proprietary dominion of Amazon.

With such a deep spirit of insubordination, it is no surprise that the community has rejected Istio like a set of loosely coupled organs rejecting a foreign skin attempting to layer itself across them. Even though the CNCF was founded by Google, the community was formed in spite of big centralized clouds, not as a marketing vessel for their products which may or may not be open source.

Microsoft seems to understand this fact better than Google, at least in the domain of service mesh.

The day after this interview with William, Microsoft announced the Service Mesh Interface (SMI), a project it partnered with Buoyant and other companies on to create a minimal spec for what a service mesh should offer to a Kubernetes deployment. The SMI presents a safe buy-in point for enterprises who want a service mesh, but do not want to get caught in the evangelistic crossfire of Istio and Linkerd.

It is in this environment that we begin our next series of shows on the current cloud native ecosystem.

Thanks to the Cloud Native Computing Foundation for putting together an amazing podcasting zone at KubeCon, and allowing me to conduct these interviews.

We are hiring two interns for software engineering and business development! If you are interested in either position, send an email with your resume to jeff@softwareengineeringdaily.com with “Internship” in the subject line.

", + "Episodes Title": "Service Mesh Wars with William Morgan", + "Episodes Uid": "SED6574534154", + "Episodes Audio File": "447f68e6cf52e5c090791599b1846789.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2fu", + "Episodes ID": "095b5840-e329-11ea-91a2-8f336f80f22e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Courtland_Meetup_Talk_mixdown.mp3", + "Episodes Pubdate Date": "2017-01-30", + "Episodes Summary": "

Engineers today have a variety of career options. You could go work for a large corporation, you could raise money and start a startup, you could freelance and move from job to job with freedom–or you could start a business with the goal of quickly becoming profitable.

Courtland Allen was a guest on Software Engineering Daily a few months ago, when he discussed Indie Hackers, a platform he built to share the stories of engineers building business on their own and making money.

We only touched the tip of the iceberg in our conversation, so I was excited to invite him to the first Software Engineering Daily Meetup, which occurred earlier this month. Today we are republishing his talk, and I would love to hear your feedback on this format. We will be experimenting more with new hosts and formats throughout 2017, and if you have ideas for the show or you are interested in hosting a show, please send me an email.

Also–the first Software Engineering Daily Meetup was fantastic–there were ~200 people showing up so we may have to cap attendance on the next one. Please join the Meetup group if you are interested, and we will let you know when we schedule our next event.

Courtland Allen slides in PDF.

", + "Episodes Title": "Making Money Online for Software Engineers with Courtland Allen", + "Episodes Uid": "SED7630753023", + "Episodes Audio File": "2f0735586415b988f8310a7374a2fb99.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jn", + "Episodes ID": "01aca70c-e329-11ea-91a2-7b3cac7bd185", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/api-design.mp3", + "Episodes Pubdate Date": "2017-04-05", + "Episodes Summary": "

There are various standards at play when creating and consuming Application Program Interfaces (APIs).  These standards, though, are mostly technical and mostly lower-level than the content of the API.

Andy Beier has experienced the broad range of API quality in his role with Domo in creating integrations with other businesses.  He has made standardization of good practices in creating APIs his mission, with an emphasis on making the right information easily accessible without having to download more than necessary.  He has traveled to meet with leaders in the field to promote standards and to make APIs easier to create and to consume.

In this episode, Andy joins Dave Rael for a conversation about API design standards, what makes for a good API, and steps in moving the broader technical community toward more useful and secure APIs.

", + "Episodes Title": "API Design Standards with Andy Beier", + "Episodes Uid": "SED3772266456", + "Episodes Audio File": "a7a1e9b5420c093cf783d4c4ea4f356c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 555, + "Episodes ID": "effa0130-e328-11ea-91a2-db019f8bc7cf", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Word2vecAdrianColyer.mp3", + "Episodes Pubdate Date": "2018-12-28", + "Episodes Summary": "

Originally posted on 13 September 2017.

Machines understand the world through mathematical representations. In order to train a machine learning model, we need to describe everything in terms of numbers.  Images, words, and sounds are too abstract for a computer. But a series of numbers is a representation that we can all agree on, whether we are a computer or a human.

In recent shows, we have explored how to train machine learning models to understand images and video. Today, we explore words. You might be thinking–”isn’t a word easy to understand? Can’t you just take the dictionary definition?” A dictionary definition does not capture the richness of a word. Dictionaries do not give you a way to measure similarity between one word and all other words in a given language.

Word2vec is a system for defining words in terms of the words that appear close to that word. For example, the sentence “Howard is sitting in a Starbucks cafe drinking a cup of coffee” gives an obvious indication that the words “cafe,” “cup,” and “coffee” are all related. With enough sentences like that, we can start to understand the entire language.

Adrian Colyer is a venture capitalist with Accel, and blogs about technical topics such as word2vec. We talked about word2vec specifically, and the deep learning space more generally. We also explored how the rapidly improving tools around deep learning are changing the venture investment landscape.

", + "Episodes Title": "Word2Vec with Adrian Colyer Holiday Repeat", + "Episodes Uid": "SED4901651328", + "Episodes Audio File": "06d6a51c041cc605f4426a1a054dd08e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5wj", + "Episodes ID": "ed5cfcd4-e328-11ea-91a2-a31aeef49b44", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_08_EdgeStorageWebAssembly.mp3", + "Episodes Pubdate Date": "2019-07-08", + "Episodes Summary": "

Edge computing allows for faster data access and computation.

When your client application makes a request, that request might be routed to the edge. Edge servers are more numerous and more widely distributed than normal data centers, but an edge server might not have all of the data or the complete application logic for the backend to serve your request.

Edge servers have historically been used for content delivery networks (CDN). CDNs are useful for hosting and serving media files that might otherwise be slow to access over a network. More recently, applications are also using edge servers for computation, as well as storage of resources which are smaller than the movies, music, and images that have traditionally been stored on an edge server.

Steve Klabnik is an engineer with Cloudflare, and he returns to the show to discuss storage at the edge. In Steve’s previous appearances we have explored Rust and WebAssembly, and we also touch on those topics in today’s episode.

", + "Episodes Title": "Edge Storage with Steve Klabnik", + "Episodes Uid": "SED6133650341", + "Episodes Audio File": "584ba88b2fea80a9796731a33f93ae7f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5u1", + "Episodes ID": "edb08052-e328-11ea-91a2-8b06f76c393e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_13_Railyard.mp3", + "Episodes Pubdate Date": "2019-06-13", + "Episodes Summary": "

Machine learning allows software to improve as that software consumes more data.

Machine learning is a tool that every software engineer wants to be able to use. Because machine learning is so broadly applicable, software companies want to make the tools more accessible to the developers across the organization.

There are many steps that an engineer must go through to use machine learning, and each additional step inhibits the chances that the engineer will actually get their model into production.

An engineer who wants to build machine learning into their application needs access to data sets. They need to join those data sets, and load them into a machine (or multiple machines) where their model can be trained. Once the model is trained, the model needs to test on additional data to ensure quality. If the initial model quality is insufficient, the engineer might need to tweak the training parameters.

Once a model is accurate enough, the engineer needs to deploy that model. After deployment, the model might need to be updated with new data later on. If the model is processing sensitive or financially relevant data, a provenance process might be necessary to allow for an audit trail of decisions that have been made by the model.

Rob Story and Kelley Rivoire are engineers working on machine learning infrastructure at Stripe. After recognizing the difficulties that engineers faced in creating and deploying machine learning models, Stripe engineers built out Railyard, an API for machine learning workloads within the company.

Rob and Kelley join the show to discuss data engineering and machine learning at Stripe, and their work on Railyard.

", + "Episodes Title": "Stripe Machine Learning Infrastructure with Rob Story and Kelley Rivoire", + "Episodes Uid": "SED4179485442", + "Episodes Audio File": "c8dba77151fb1f2b70849c032c893996.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ab", + "Episodes ID": "10a0fb8c-e329-11ea-91a2-9791f4dbf460", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/winningwithdata_edited_2.mp3", + "Episodes Pubdate Date": "2016-11-15", + "Episodes Summary": "

Large technology companies have no shortage of data. But raw data itself does not provide a competitive advantage. Many companies are bottlenecked by a shortage of data scientists who can query that data effectively. This results in an organizational dysfunction where people lining up to ask questions of the data science team are unable to move as fast as they want to.

Tomasz Tunguz saw this when he was working at Google, and he continues to see it today from his position at Redpoint, where he works as a venture capitalist looking at companies. The problems with the “data supply chain” led him to write “Winning With Data”, a book about how technology companies can successfully operationalize, explore, and act on their data.

We’ve done many shows about the interactions between software engineers, data engineers, and data scientists. This episode is a great complement to previous episodes, providing a holistic view into the way data moves through an organization–and I highly recommend Tomasz’s book “Winning with Data”.

", + "Episodes Title": "Winning With Data with Tomasz Tunguz", + "Episodes Uid": "SED1193659962", + "Episodes Audio File": "4a88c28815b59a6b3ab75be48790cb5e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 613, + "Episodes ID": "ecddc32e-e328-11ea-91a2-dfc294330789", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_08_DataasaService.mp3", + "Episodes Pubdate Date": "2019-08-08", + "Episodes Summary": "

Data-as-a-service businesses offer paid access to data sets. These data sets can be useful for building products or training machine learning models. 

There has been steady growth in the tools and practices around processing and storing data. But access to data sets remains a bottleneck for widespread development of machine learning applications in a large set of domains. 

SafeGraph is a company focused on the problem of data-as-a-service. Today, SafeGraph’s primary product is reliable, up-to-date location information on places. The data for these points-of-interest needs be acquired, verified, cleaned, made accessible through an API, and intelligently priced. 

In previous episodes with SafeGraph, we have explored the basic premise of data businesses and why they are important platforms for building futuristic data products that are impossible for entrepreneurs to build today. SafeGraph CEO Auren Hoffman returns to the show to discuss the data as a service business model.

Software-as-a-service has existed as a category for more than a decade. Infrastructure-as-a-service has existed for just as long. Data-as-a-service is much more undeveloped. Auren recently published the “Data-As-A-Service Bible: Everything You Wanted To Know About Running A DaaS Business”. This was a very useful article, as it breaks down a category of software that is almost entirely unexplored.

", + "Episodes Title": "Data-As-A-Service with Auren Hoffman", + "Episodes Uid": "SED2634339228", + "Episodes Audio File": "5defdd762ea7a53c17717196b4f11152.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2hl", + "Episodes ID": "06752b06-e329-11ea-91a2-ef044829c03e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/realmdb_edited.mp3", + "Episodes Pubdate Date": "2017-02-22", + "Episodes Summary": "

Expectations for mobile apps have gone up steadily since the iPhone was released. But the choice of databases built for mobile apps has remained limited mostly to SQLite. RealmDB was created as a new option for mobile developers on iOS, Android, or any other mobile platform.  

Realm is not just a database. It is a database platform, offering a variety of systems such as authentication, sync, and an event framework. In this interview with RealmDB VP of engineering Brian Munkholm, he explains why we need not only a new mobile database type, but an entire database platform. We talk about the business of mobile, IoT, cloud, and cross platform. It’s a wide ranging conversation, but also deeply technical.

", + "Episodes Title": "RealmDB with Brian Munkholm", + "Episodes Uid": "SED2997211299", + "Episodes Audio File": "0f3e49417c2e579ea5a7b113173e2cbd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "35m", + "Episodes ID": "f5f6c398-e328-11ea-91a2-5ba15ef75166", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/QuantumComputing.mp3", + "Episodes Pubdate Date": "2017-10-23", + "Episodes Summary": "

Computer chips have physical limitations. When transistors get too small, electrons start to behave in ways that make the hardware modules less reliable. Our reliable technological progress has been enabled by Moore’s Law: the idea that the number of components we can fit on a chip doubles roughly every 12-18 months.

We can’t keep shrinking the size of these components, because physics is no longer complying.

Quantum computing allows us to operate on qubits rather than bits, giving us better parallelism and continued reliable technological progress. Quantum computing is still mostly an area of research rather than production systems–but it is rapidly approaching usability, and Zlatko Minev joins the show to explain how quantum computing works, and why software engineers should care.

Zlatko is a PhD candidate at the Yale Quantum Information Lab. Today he describes how qubits work, which algorithms quantum computing impacts, and which parts of modern computer architecture will work on a quantum computer. We may have to throw out the Von Neumann architecture when it comes to quantum!

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Quantum Computing Introduction with Zlatko Minev", + "Episodes Uid": "SED5735333518", + "Episodes Audio File": "aa17f1ef07da3058204014e00f9f6c84.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 359, + "Episodes ID": "f6049c8e-e328-11ea-91a2-6ff0e7f6f2fa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ModelTraining.mp3", + "Episodes Pubdate Date": "2017-10-18", + "Episodes Summary": "

Machine learning models can be built by plotting points in space and optimizing a function based off of those points.

For example, I can plot every person in the United States in a 3 dimensional space: age, geographic location, and yearly salary. Then I can draw a function that minimizes the distance between my function and each of those data points. Once I define that function, you can give me your age and a geographic location, and I can predict your salary.

Plotting these points in space is called embedding. By embedding a rich data set, and then experimenting with different functions, we can build a model that makes predictions based on those data sets. Yufeng Guo is a developer advocate at Google working on CloudML. In this show, we described two separate examples for preparing data, embedding the data points, and iterating on the function in order to train the model.

In a future episode, Yufeng will discuss CloudML and more advanced concepts of machine learning.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Model Training with Yufeng Guo", + "Episodes Uid": "SED1179289184", + "Episodes Audio File": "69f8a1a70a280fd143ea80c76edb88f9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3q6", + "Episodes ID": "f3449c60-e328-11ea-91a2-d77ce4e934e4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_01_AnatomyofNext.mp3", + "Episodes Pubdate Date": "2018-05-01", + "Episodes Summary": "

Technology is pushing us rapidly toward a future that is impossible to forecast. We try to imagine what that future might look like, and we can’t help having our predictions shaped by the media we have consumed.

1984, Terminator, Gattaca, Ex Machina, Black Mirror–all of these stories present a dystopian future. But if you look around the world, the most successful technologists are mostly guided by a sense of optimism. Technologists themselves are mostly idealistic–they see the future through a utopian lens. Popular media largely tells a different story: that we are headed for a dystopian world.

Why is there such a gulf in the level of idealism between technologists and the media?

Mike Solana found himself asking that question on a regular basis during his work at Founder’s Fund, where he is a vice president. Founder’s Fund has a bias toward funding difficult, cutting-edge technology like gene editing, robotics, and nuclear energy. This technology that Mike was seeing made him excited about the future–which led to his creation of the podcast “Anatomy of Next.”

“Anatomy of Next” has explored biology, robotics, nuclear energy, superintelligence, and the nature of reality. Soon the podcast will be exploring how our civilization will explore and settle the solar system–specifically Mars.

I’ve listened through the entire first season of the show twice and enjoyed it so much because Mike explores questions that are on the border of philosophy and technology–questions about the nature of reality, and what makes us human–and nobody can give perfect answers to these questions. But Mike interviews top experts on the show, which provides us with a framework. Guests on “Anatomy of Next” include Nick Bostrom (the author of Superintelligence), George Church (a pioneer in gene editing), and Palmer Luckey (the founder of VR company Oculus).

Mike joins the show to talk about why he started “Anatomy of Next,” and his own perspective on the future.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Technology Utopia with Michael Solana", + "Episodes Uid": "SED7115399315", + "Episodes Audio File": "edb8504f064a1f6c63bb1c00dc5cdf2f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4jq", + "Episodes ID": "f140d820-e328-11ea-91a2-0b060e7790ff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/09_23_2018_Front.mp3", + "Episodes Pubdate Date": "2018-09-24", + "Episodes Summary": "

Front is a shared inbox application that has seen rapid adoption within companies. Front allows multiple members of a company to collaborate together on a conversation–whether that conversation is in email, Twitter, or Facebook Messenger. This is useful when a customer email needs to be shared between the sales and engineering teams, or when a single email address is shared between different members of the same team, such as “contact@softwareengineeringdaily.com”.

This might sound like a niche problem, but it is actually a problem faced somewhere within every single company. Because the problem of shared inbox is so prevalent, the company has grown its user base quickly, scaling the team as well as the infrastructure.

The sensitivity of the data (emails) that Front is handling means that security is paramount. And as users of Front rely on it more and more as a central point of communication, uptime and consistency needs to be maintained.

Laurent Perrin is the CTO at Front, and he joins the show to describe the software architecture and product strategy for Front. It was a fascinating show, and we covered the full stack. On the backend, Front pulls emails into S3 buckets and maintains the schema of the inbox in a SQL database. The desktop Front client is written in Electron, which is a way to write desktop applications in HTML5, JavaScript, and CSS.

We also talked about the system for keeping the communications “real-time”–it’s important that users are aware of what each other is doing, since you don’t want to be preparing a response to an email at the same time I am.

", + "Episodes Title": "Front Engineering with Laurent Perrin", + "Episodes Uid": "SED2026137241", + "Episodes Audio File": "da38f5e51989561389c1520400d4ac4f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3k8", + "Episodes ID": "f400e2c6-e328-11ea-91a2-83ef7d072cd6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_09_ProofofStake.mp3", + "Episodes Pubdate Date": "2018-03-09", + "Episodes Summary": "

For a decade, Bitcoin’s proof-of-work system has run without disruption. In a proof-of-work scheme, Bitcoin miners compete to solve a cryptographic puzzle associated with a block of transactions.

Every ten minutes, all the Bitcoin miner nodes race to be the first to solve a block of transactions. Only one miner wins each block, meaning the other nodes’ time was ultimately wasted. There is also a massive expense of electricity.

Bitcoin is a system with low transaction throughput—about 7 transactions per second. Computer scientists have wondered—is there an alternative way of doing consensus? What if we took all the wasted compute power from proof of work, and allocated it in a way that makes transactions get processed faster?

But Bitcoin’s governance tends to be extremely conservative. A change to the consensus mechanism probably won’t happen any time soon in Bitcoin.

Ethereum’s consensus mechanism is modeled after that of Bitcoin—proof-of-work mining. But Ethereum’s governance ethos is quite different. Ethereum is in the process of planning and implementing proof of stake, an alternative consensus mechanism in which trusted validators are chosen to validate blocks of transactions.

Subhan Nadeem is a student at the University of Waterloo where he studies computer science and business. He is the author of several popular articles on Medium that explain blockchain concepts. He joins the show to talk about crypto from the point of a student—and gives us a great walk through of different consensus mechanisms.

To find all of our old episodes about cryptocurrencies, check out our apps in the  iOS or Android app store. They have all 700 of our episodes, with recommendations, related links, discussions and more. And it’s all open source–if you are looking for an open source project to contribute to, come check us out at github.com/softwareengineeringdaily. We welcome all kinds of contributors–new developers and experts. Engineers and non-technical people.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Proof of Stake with Subhan Nadeem", + "Episodes Uid": "SED2992151346", + "Episodes Audio File": "3340b4f459bdce1efd34fa003b54ddff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ir", + "Episodes ID": "04b6286a-e329-11ea-91a2-336f65584a56", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/CloudNativeComputing.mp3", + "Episodes Pubdate Date": "2017-03-13", + "Episodes Summary": "

Making the right engineering choices in today’s wide landscape of cloud technologies is hard. Predicting the future in order to invest in companies in this space has the same level of complexity.

The cost of cloud computing is going down but the volume of total required space and processing power is going up. The open source community is growing and improving but people are increasingly willing to buy software that will save them time.

Capital is flowing into Silicon Valley at a faster rate than can be sensibly absorbed by the number of quality companies. A decent product won’t have trouble raising money. But a decent investor has to choose wisely among the huge selection of available opportunities.

Lenny Pruss works at Amplify Partners where he is currently focused on the cloud native space. In this episode, we talk about what cloud native means and how to navigate the complex landscape, whether you are an engineer or an investor.

Cloud Native Landscape Project

", + "Episodes Title": "Cloud Native Investing with Lenny Pruss", + "Episodes Uid": "SED7613193142", + "Episodes Audio File": "fa2192248c3c7d7d6e96149d472f0c26.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "vv", + "Episodes ID": "2dead474-e329-11ea-91a2-a7106d87f560", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/treehouse_postgband2.mp3", + "Episodes Pubdate Date": "2015-10-30", + "Episodes Summary": "

Treehouse is an online school that teaches software development, design and strategy.

Ryan Carson is the CEO and Founder of Treehouse.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Treehouse with Ryan Carson", + "Episodes Uid": "SED7909040344", + "Episodes Audio File": "497c847285f55e4b00c99635d0a472cb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4un", + "Episodes ID": "f0b81936-e328-11ea-91a2-a765a94b2ea1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_1_Wonolo.mp3", + "Episodes Pubdate Date": "2018-11-01", + "Episodes Summary": "

Online labor marketplaces are widely used for one-to-one transactions. On Uber, a rider hires a driver for transportation. On TaskRabbit, a homeowner hires a cleaner to come clean their kitchen.

These types of marketplaces are not as widely used for one-to-many transactions, but they can be just as useful. A warehouse owner would want to hire a group of workers to help with holiday shipments. A conference organizer would want to hire a group of event staffers to help run the conference.

Wonolo is an on-demand staffing platform. Businesses post jobs and workers apply for those jobs. The types of work include event staffing, warehouse operations, merchandising, and other general labor tasks. In past shows, we have covered on-demand work platforms such as Fiverr, Thumbtack, Uber, and Instacart. Wonolo presents another variation in the business model and software architecture of the gig economy.

Jeremy Burton is the CTO and chief data scientist at Wonolo. He joins the show to talk about building and scaling Wonolo, and some of the key strategic decisions that Wonolo has made along the way. As with any successful marketplace business, Wonolo has solved the chicken and egg problem of how to get supply and demand on the platform simultaneously. The company has grown deliberately, setting up operations in one city at a time to make sure that they can provide a good experience in both sides of the market in each of the new geographies.

Jeremy and I also talked about the broader effects that the gig economy could potentially have on the labor market. Gig economy platforms use a 5-star rating system and written reviews to judge workers, instead of a resume system. The gig economy allows for rapid job liquidity, and the potential for workers to steadily “level up” more quickly than they might be able to in a typical corporate job. These aspects of the gig economy are rarely discussed, so it was enlightening to hear Jeremy’s views on them.

", + "Episodes Title": "Wonolo: Staffing Marketplace with Jeremy Burton", + "Episodes Uid": "SED7516122752", + "Episodes Audio File": "0fd1df9d15e9de9e88d1d48254fcb8e0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2m5", + "Episodes ID": "ffb63a62-e328-11ea-91a2-27376dfbd6e3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/swiftontheserver_edited.mp3", + "Episodes Pubdate Date": "2017-04-19", + "Episodes Summary": "

Swift is a language that is most commonly used to write apps for Apple client devices, such as iPhones. Since being released in 2014, Swift has become one of the most popular languages due to its high performance and developer ergonomics. In 2015, Swift was open sourced, creating the opportunity for Swift to be used outside of the Apple ecosystem.

If you write an iPhone app today, your frontend is in Swift and your backend is probably in NodeJS, Java, or Ruby. Engineers are working to port Swift to the server so that the Swift developer experience is isomorphic: the same language on the backend and the frontend.

Chris Bailey is an engineer at IBM working on Kitura, a Swift web framework. In this episode, we discuss the history of Swift, why it is so appealing to developers, and why Swift could become a server side language with as much popularity as Java.

Software Engineering Daily is having our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

", + "Episodes Title": "Swift on the Server with Chris Bailey", + "Episodes Uid": "SED6053278516", + "Episodes Audio File": "30d442c494f1583e982cb0070a5ec405.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3s2", + "Episodes ID": "f30823fc-e328-11ea-91a2-6f171c709646", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_17_Pulsar.mp3", + "Episodes Pubdate Date": "2018-05-17", + "Episodes Summary": "

Message broker systems decouple the consumers and producers of a message channel. In previous shows, we have explored ZeroMQ, PubNub, Apache Kafka, and NATS. In this episode, we talk about another message broker: Apache Pulsar.

Pulsar is an open source distributed pub-sub message system originally created at Yahoo. It was used to scale products with high volumes of users–such as Yahoo Mail.

There are three components of a Pulsar deployment: the Pulsar broker (which handles the message brokering), Apache Bookkeeper (which handles the durable storage of the messages), and Apache Zookeeper, which manages the distributed coordination.

Lewis Kaneshiro joins the show to describe how Apache Pulsar works, and how it compares to other messaging systems like Apache Kafka. Lewis is the CEO of Streamlio, a company that builds messaging and stream processing systems for enterprises, and uses Pulsar in its core product.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Pulsar Messaging with Lewis Kaneshiro", + "Episodes Uid": "SED7549827227", + "Episodes Audio File": "f1ecbfa25e43dc8bf678a7df6c3c4f41.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32o", + "Episodes ID": "f65f72b2-e328-11ea-91a2-27b52aa20779", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/TinderGrowthEngineering.mp3", + "Episodes Pubdate Date": "2017-09-21", + "Episodes Summary": "

Tinder is a popular dating app where each user swipes through a sequence of other users in order to find a match. Swiping left means you are not interested. Swiping right means you would like to connect with the person. The simple premise of Tinder has led to massive growth, and the app is now also used to discover new friends and create casual meetings.

Every social network knows–if you are not growing, then you are dying. Growth is so important to Tinder, they have a large engineering organization devoted to five facets of growth: new users, activation, retention, dropoff, and anti-spam.

These five segments cover the entire Tinder user lifecycle, and there is a sub-team in charge of each of the five areas. No matter what kind of Tinder user you are, there are growth engineers focused on your experience.

Alex Ross is the director of engineering for the growth team at Tinder. His job requires a mix of data science, data engineering, psychology, and setting proper KPIs (key performance indicators). Each subteam has KPIs that determine how well they are doing with growth–and if the wrong KPI is set, it can create bad incentives. For example, a growth team that is focused only on getting users to spend more time engaging with Tinder would have an incentive to create so-called “dark patterns” that trigger addiction.

", + "Episodes Title": "Tinder Growth Engineering with Alex Ross", + "Episodes Uid": "SED9310273056", + "Episodes Audio File": "17f27984090ac943eacb4734af5b75e5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 604, + "Episodes ID": "ecefb93a-e328-11ea-91a2-e706986ae1c8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_02_CareerKarma.mp3", + "Episodes Pubdate Date": "2019-08-01", + "Episodes Summary": "

Coding bootcamps allow anyone to become a programmer at a faster pace than the traditional computer science education system. In the last five years, coding bootcamps have grown rapidly in popularity, with thousands of people gaining the necessary skills to work as a software engineer.

Career Karma is a platform that allows individuals to find the best coding bootcamp. There are many coding bootcamps, and they are not all the same. Much like different schools have different cultures and focus on different disciplines, coding bootcamps vary widely in their teaching styles and acceptance path.

Reuben Harris and Artur Meyster are co-founders of Career Karma, and they join the show to discuss the changing nature of software engineering education and the frictions that new programmers encounter as they navigate the world of coding bootcamps. They also describe their journey to entrepreneurship and their own personal experience with coding bootcamps.

", + "Episodes Title": "Career Karma: Coding Bootcamp Platform with Ruben Harris and Artur Meyster", + "Episodes Uid": "SED3467082472", + "Episodes Audio File": "ba512ecf615b6394e87df155e74c6fc2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2pl", + "Episodes ID": "fbb99eb8-e328-11ea-91a2-df533f0b9579", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/TechinMiddleeast.mp3", + "Episodes Pubdate Date": "2017-05-11", + "Episodes Summary": "

Many countries in the developing world are undergoing a technological revolution which is shaping how they tackle problems around infrastructure, health, education and finance. Young people are at the forefront of developing solutions to the problems in the developing world. These young people creating technology and businesses to foster innovation and growth.

Countries in the Middle East are no exception to this. Despite the difficulties the region faces such as the wars in Syria and Yemen, its populations are well-informed, plugged in and are using technology to build the future of their societies.

In the book Startup Rising published in 2013, Washington D.C.- and New York City-based entrepreneur and venture investor Chris Schroeder wrote about how the rest of the world, especially the West, needed to wake up to what was happening in the Middle East. In today’s episode, Chris talks to Carl Mungazi about what he has seen throughout his travels in the Middle East. He discusses the successes and challenges faced by the entrepreneurs who shared their stories with him and what this means for those watching in the West.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Tech in the Middle East with Chris Shroeder", + "Episodes Uid": "SED8590245742", + "Episodes Audio File": "9cf39f945b091db7ff4629f6f37ff504.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2y4", + "Episodes ID": "f70a281a-e328-11ea-91a2-a36c3b9576ad", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/HerokuCI.mp3", + "Episodes Pubdate Date": "2017-08-02", + "Episodes Summary": "

Continuous delivery is a model for deploying small, frequent changes to an application. In a continuous delivery workflow, code changes that are pushed to a repository set off a build process that spins up a new version of the application. Testing is performed against that new build before advancing it to production, merging it with the existing codebase.

Many continuous delivery products are getting built today because it is a wide open space–much like cloud providers or monitoring tools. There are subjective product and engineering decisions to be made depending on the audience for the product.

Heroku Flow is a continuous delivery platform built on top of Heroku, a platform as a service. Andy Appleton is an engineer at Heroku and he joins the show to describe how Heroku Flow was built. Two years of work went into the project from initial conception to launch.

Full disclosure: Heroku is a sponsor of Software Engineering Daily.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Platform Continuous Delivery with Andy Appleton", + "Episodes Uid": "SED8338738503", + "Episodes Audio File": "25ffd077c2f1d399611a0873b62712de.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3sm", + "Episodes ID": "f2f5cea0-e328-11ea-91a2-0757581f8ce1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_22_ContainerSecurity.mp3", + "Episodes Pubdate Date": "2018-05-22", + "Episodes Summary": "

Deploying software to a container presents a different security model than deploying an application to a VM. There is a smaller attack surface per container, but the container is colocated on a node with other containers. Containers are meant to have a shorter lifetime than VMs, so there are generally fewer consequences if a container needs to be destroyed and rebuilt due to a potential security vulnerability.

Maya Kaczorowski works on container security at Google. In a recent talk at KubeCon, Maya discussed runtime security of containers on Kubernetes. Maya joins the show to discuss container security, and what it means to software developers and operators.

Maya also gives guidelines for evaluating the security of your own cluster. We talked about the security benefits of a managed Kubernetes provider, and also explored how some container security vendor software works.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Container Security with Maya Kaczorowski", + "Episodes Uid": "SED6166287357", + "Episodes Audio File": "c47176eb43f0c1368a874ebfc23ce7c2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3of", + "Episodes ID": "f376e99a-e328-11ea-91a2-8b1aa941e359", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_17_MLDatawithAurenHoffman.mp3", + "Episodes Pubdate Date": "2018-04-18", + "Episodes Summary": "

Machine learning tools are rapidly maturing. TensorFlow gave developers an open source version of Google’s internal machine learning framework. Cloud computing provides a cost effective, accessible way of training models. Edge computing allows for low latency deployments of models.

But even if you are a kid with a laptop who has learned all the machine learning algorithms, read all of the deep learning textbooks, and figured out how to use AWS, all of the tooling and education in the world doesn’t change the fact that you still need data to build models.

This illustrates why we need data-as-a-service.

A kid with a laptop has access to infrastructure-as-a-service, platform-as-a-service, and software-as-a-service. As these tools build on each other, there has been an explosion of high-leverage software products. But the world of data sets remains crude and underdeveloped.

Think about some data sets you could take advantage of: the number of emergency room patients that come into a hospital with chest pain; the size of the average coffee mug; the principal component breakdown of sidewalk concrete in San Francisco.

SafeGraph is a company that offers data sets as a service. Auren Hoffman is the CEO of SafeGraph, and he joins the show to discuss why he started building SafeGraph and how he thinks about the state of publicly accessible data.

Auren was previously on the podcast, and I always enjoy talking to him–this was a great episode and I think you will like it as well. Full disclosure: LiveRamp is a sponsor of Software Engineering Daily, LiveRamp being the company that Auren created prior to SafeGraph.

Raj Chetty economic papers

Paul Graham “Keep Your Identity Small”

Auren Hoffman on Quora

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "SafeGraph with Auren Hoffman", + "Episodes Uid": "SED9842033388", + "Episodes Audio File": "79fea2755dbb24d819aef6500d7a5c76.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "53i", + "Episodes ID": "f031baee-e328-11ea-91a2-e7fb0ce9c201", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_12_EladGil.mp3", + "Episodes Pubdate Date": "2018-12-12", + "Episodes Summary": "

When a startup finds product market fit, the adoption of that product can grow rapidly, turning a startup into a high growth company.

All of a sudden, a startup that was struggling to find its first customer is bombarded with new challenges. The startup has to hire tens of new employees. This requires raising capital, so the startup has to meet with investors and lawyers. A rapid influx of new customers puts a strain on the engineering and customer service elements of the company.

There is too much to do, and there is only so much time in a day.

The CEO of the high-growth company is up late into the night, answering emails and losing sleep. But these are good problems to have, and the company is in a state of exuberance. The CEO must balance psychological health with the stressful task of scaling a company.

Elad Gil is an entrepreneur and author of “High Growth Handbook”, a book of lessons and guidelines about how to navigate a startup that has found product market fit, and is beginning to scale. High Growth Handbook includes interviews with experienced entrepreneurs such as Marc Andreessen and Patrick Collison, whom Elad met with as he wrote the book.

Elad joins the show to discuss his book, and his own personal lessons of working with companies such as Twitter, Google, Stripe, and Coinbase. Elad has worked at several high growth companies and invested in others, and he has gathered a lot of wisdom from these different experiences.

", + "Episodes Title": "High Growth Handbook with Elad Gil", + "Episodes Uid": "SED5306832837", + "Episodes Audio File": "c0e107b88799bc52377fbc9b84eb8a6d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ef", + "Episodes ID": "ef2eadc8-e328-11ea-91a2-7b2e87f904c4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_01_InternetHistory.mp3", + "Episodes Pubdate Date": "2019-03-01", + "Episodes Summary": "

The Internet has transformed humanity.

The Internet is the result of a long series of innovations from military, academia, business, and the open source community. In his book, How The Internet Happened: From Netscape to the iPhone, Brian McCullough tells the story of the last 25 years of Internet development through the lens of companies like ebay, Amazon, Google, and Apple.

Whereas other books have focused on the trajectory of these individual companies, Brian explains how innovations in one company often lead to success in another. Without the lessons from Napster, we might not have Spotify. Without the trust model pioneered by ebay, we would not have marketplaces like Airbnb.

Brian is also the host of The Internet History Podcast and the Techmeme Ride Home podcast. In The Internet History Podcast, Brian interviews entrepreneurs and engineers who were firsthand witnesses to the developments that led to our modern Internet, including early employees at Amazon, Tesla, and TheGlobe.com. In his other podcast, the Techmeme Ride Home, Brian gives a daily overview of the day’s Internet news.

Through his podcasts about the Internet’s past and present, Brian has also accumulated an intuition about the future. He joins the show to discuss his book, the art of podcasting, and the historical lessons of technology.

", + "Episodes Title": "Internet History (and Future) with Brian McCullough", + "Episodes Uid": "SED8865939553", + "Episodes Audio File": "77c4217a8b4856b72e1726e869716e61.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 600, + "Episodes ID": "ed0142fe-e328-11ea-91a2-134b2929f484", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_29_DataMeshandMachineLearning.mp3", + "Episodes Pubdate Date": "2019-07-29", + "Episodes Summary": "

Data engineering involves numerous tools–a data lake, databases, data warehouses, numerous APIs, streaming systems, and microservices. There is no shortage of ways to interact with data and manage data, but many companies are struggling to figure out design patterns and best practices for how to manage data and build data infrastructure.

Zhamak Dehgani is a principal consultant and portfolio director with ThoughtWorks, where she works with enterprises to improve their software systems and workflows. She is the author of an article called How to Move Beyond a Monolithic Data Lake to a Distributed Data Mesh and she joins the show to discuss her perspective on data infrastructure, as well as the “data mesh” concept that she has coined.

Data mesh represents the movement away from having a centralized data lake that all teams interact with, and towards having different data products and individual data management systems for individual domain teams.

", + "Episodes Title": "Data Mesh with Zhamak Deghani", + "Episodes Uid": "SED6719844377", + "Episodes Audio File": "cf970caf4f16dc6023b0a3cd4b9dd1e5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "44w", + "Episodes ID": "f26252a6-e328-11ea-91a2-77016e8f7412", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_07_03_FintechInvesting.mp3", + "Episodes Pubdate Date": "2018-07-03", + "Episodes Summary": "

Computer systems consume memory, CPU, battery, data, and network bandwidth as inputs. These systems provide value for the end user by delivering information, virtual objects, and physical products as outputs. Another fundamental resource that is becoming easier to consume as input is money. There are also new outputs–financial constructs that are made possible by cloud computing, machine learning, and cryptocurrencies.

This is why so much opportunity exists in fintech. Money has always been a flexible tool for brokerage between humans. But as recently as the early 2000s, the interfaces between money and computers have been clunky and inflexible. Engineers that wanted to build financial systems around money had to work directly with banks and credit card processors.

More recently, there has been an explosion in new APIs and completely new financial primitives like cryptocurrencies. In the year 2000, a well-funded team had to struggle to put together a basic ecommerce company. Today, a blue ocean of opportunity has opened up for entrepreneurs building businesses around lending, insurance, underwriting, banking, and every other microcosm of the financial system.

Michael Walsh is a general partner and co-founder of Green Visor Capital. In today’s episode, he described his perspective on the modern fintech environment, and what the future holds.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Fintech Environment with Michael Walsh", + "Episodes Uid": "SED8933027633", + "Episodes Audio File": "41464fbf27a0041d43b6cf89b4ad1629.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3jo", + "Episodes ID": "f4185898-e328-11ea-91a2-abcff118cd0c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_02_DogecoinJacksonPalmer.mp3", + "Episodes Pubdate Date": "2018-03-02", + "Episodes Summary": "

Dogecoin was started in 2013 as a joke. Jackson Palmer forked Bitcoin and created his cryptocurrency as a play off the “doge” meme. The currency became popular as a means of reddit users “tipping” each other. If I made a comment on reddit that you liked, you might send me some Dogecoin. This use case allowed people to share the idea of Dogecoin virally, and Dogecoin became valuable, even though the currency did not have any technical properties that made it significantly different than Bitcoin.

As Dogecoin was becoming popular, an experienced Internet scam artist took notice and started a Dogecoin exchange called Moolah. Moolah was used to steal money from its customers and investors, and the CEO was arrested.

Jackson Palmer was not involved in this scheme, but it soured his feelings about Dogecoin and the entire Bitcoin space. His coin, which had been created as a joke, had been repurposed as a weapon to steal money.

Jackson left the Dogecoin community in 2015 to focus on other things. But as Bitcoin entered the mainstream conversation, Jackson has been pulled back into the world of cryptocurrency. Jackson’s YouTube channel has over 20,000 subscribers, who tune into learn about consensus protocols, new tokens, and cryptocurrency news.

In today’s episode, Jackson and I discuss his experiences with Dogecoin, and how that compares with the scams around low-quality ICOs that are pulling in retail investors today. We also discuss more positive things–such as proof-of-stake and newer consensus protocols.

If you are looking for an internship, apply to the Software Engineering Daily internship, at softwaredaily.com/jobs. And if you are looking to recruit engineers, you can post jobs for your company there as well–it’s completely free to post jobs and to apply. We are hoping to find interns to contribute to the Software Daily open source project–and if you want to see what we are building, go to SoftwareDaily.com or check out our apps in the  iOS or Android app store. They have all 650 of our episodes, with recommendations, related links, discussions and more.

Also–Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Dogecoin with Jackson Palmer", + "Episodes Uid": "SED3774937703", + "Episodes Audio File": "d0a46e4c01ed359091546202aacaf215.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "53v", + "Episodes ID": "f02844b4-e328-11ea-91a2-7f078ea2bc4c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_12_14_WesBos.mp3", + "Episodes Pubdate Date": "2018-12-14", + "Episodes Summary": "

Wes Bos has created popular courses on React, GraphQL, and JavaScript. With hundreds of thousands of students, Wes has earned a cult following for his fun, practical lessons on web development. The courses produced by Wes teach developers how to build useful applications such as a complete e-commerce store.

Wes has built a career around studying and evangelizing JavaScript. His approach to education centers around practice, repetition, and hacking on fun projects. He also co-hosts a podcast called SyntaxFM, and is a frequent Twitter user.

Wes is a rare mix of developer, teacher, businessman, and designer. Throughout his work, there is an artist’s sense of attention to detail, and a modern entrepreneur’s sense of pricing and marketing. His sites, such as JavaScript30 and React For Beginners have the deliberate style of someone who has been building websites for a very, very long time.In today’s episode, Wes Bos joins the show to give his perspective on JavaScript, entrepreneurship, and podcasting. To learn more about Wes’s business and his background, check out the IndieHackers podcast with him.

", + "Episodes Title": "Full Stack JavaScript with Wes Bos", + "Episodes Uid": "SED3961749131", + "Episodes Audio File": "4d83ee19e968af58bee67ffe1ec21a61.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2pm", + "Episodes ID": "fba18918-e328-11ea-91a2-eb9b83aa8b3a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Libratus.mp3", + "Episodes Pubdate Date": "2017-05-12", + "Episodes Summary": "

Humans have now been defeated by computers at heads up no-limit holdem poker.

Some people thought this wouldn’t be possible. Sure, we can teach a computer to beat a human at Go or Chess. Those games have a smaller decision space. There is no hidden information. There is no bluffing. Poker must be different! It is too human to be automated.

The game space of poker is different than that of Go. It has 10^160 different situations–which is more than the number of atoms in the universe. And the game space keeps getting bigger as the stack sizes of the two competitors gets bigger.

But it is still possible for a computer to beat a human at calculating game theory optimal decisions–if you approach the problem correctly.

Libratus was developed by CMU professor Tuomas Sandholm, along with my guest today Noam Brown. The Libratus team taught their AI the rules of poker, they gave it a reward function (to win as much money as possible), and they told it to optimize that reward function. Then they had Libratus train itself with simulations.

After enough training, Libratus was ready to crush human competitors, which it did in hilarious, entertaining fashion. There is a video from Engadget on YouTube about the AI competing against professional humans.

In this episode, Noam Brown explains how they built Libratus, what it means for poker players, and what the implications are for humanity–if we can automate poker, what can’t we automate?

", + "Episodes Title": "Poker Artificial Intelligence with Noam Brown", + "Episodes Uid": "SED1584778319", + "Episodes Audio File": "31bce463d564cd5472dee648fec32d4f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2h8", + "Episodes ID": "06ea8dce-e329-11ea-91a2-379797a90f06", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/MLwithAuren.mp3", + "Episodes Pubdate Date": "2017-02-17", + "Episodes Summary": "

If you wanted to build a machine learning model to understand human health, where would you get the data? A hospital database would be useful, but privacy laws make it difficult to disclose that patient data to the public. In order to publicize the data safely, you would have to anonymize it, so that a patient’s identity could not be derived from data about that patient–and true anonymization is notoriously difficult.

In every industry where privacy is a concern there is a similar challenge. If there is no place with public data sets, there is no place where the machines can go to learn. The possible machine learning applications that we can build are limited by the data sets that are available.

Auren Hoffman started his company SafeGraph to unlock data sets so that machine learning algorithms can learn from that data. In this episode, we talk about the machine learning landscape in both the short- and long-term time horizons. We also discussed some of Auren’s strategies for building companies, which have been crucial for me in thinking about how to build Software Engineering Daily.

Where Should Machines Go to Learn?

Quoracast Episode

", + "Episodes Title": "Where Machines Go to Learn with Auren Hoffman", + "Episodes Uid": "SED1273248995", + "Episodes Audio File": "853b73b7571be71688f9c5b403db665a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jl", + "Episodes ID": "03c5f05c-e329-11ea-91a2-7bed890043c9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Wearables.mp3", + "Episodes Pubdate Date": "2017-03-22", + "Episodes Summary": "

Wearables have become more accessible to the public. Snap’s spectacles, Google Glass, FitBit, and Apple Watch suggest a future in which many people will be wearing a smart device. In this episode Asta Roseway, Research Designer at Microsoft Research, gives insights into other categories of wearables like tattoos, scarves, and cosmetics.

Asta talked about her work on DuoSkin, a wearable that looks like a beautiful metallic tattoo. We talked about its capabilities and how it was built, and why it is still too early for connected tattoos. We also talked about the intersection between health, wearables, technology, and fashion and how wearables might look in the near future.

This episode is guest hosted by Edaena Salinas, who also hosts The Women in Tech Show.

Asta Roseway’s Website

Asta Roseway Microsoft Research 

MoodWings

LightWear

", + "Episodes Title": "Wearables with Asta Roseway", + "Episodes Uid": "SED4773427781", + "Episodes Audio File": "394604ea6776012df1b97172f5edb423.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7bt", + "Episodes ID": "e8eb216c-e328-11ea-91a2-af19c9421f3a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_31_MartinFord.mp3", + "Episodes Pubdate Date": "2020-06-15", + "Episodes Summary": "

Originally published January 31, 2019

Artificial intelligence is reshaping every aspect of our lives, from transportation to agriculture to dating. Someday, we may even create a superintelligence–a computer system that is demonstrably smarter than humans. But there is widespread disagreement on how soon we could build a superintelligence. There is not even a broad consensus on how we can define the term “intelligence”.

Information technology is improving so rapidly we are losing the ability to forecast the near future. Even the most well-informed politicians and business people are constantly surprised by technological changes, and the downstream impact on society. Today, the most accurate guidance on the pace of technology comes from the scientists and the engineers who are building the tools of our future.

Martin Ford is a computer engineer and the author of Architects of Intelligence, a new book of interviews with the top researchers in artificial intelligence. His interviewees include Jeff Dean, Andrew Ng, Demis Hassabis, Ian Goodfellow, and Ray Kurzweil.

Architects of Intelligence is a privileged look at how AI is developing. Martin Ford surveys these different AI experts with similar questions. How will China’s adoption of AI differ from that of the US? What is the difference between the human brain and that of a computer? What are the low-hanging fruit applications of AI that we have yet to build?

Martin joins the show to talk about his new book. In our conversation, Martin synthesizes ideas from these different researchers, and describes the key areas of disagreement from across the field.

", + "Episodes Title": "Architects of Intelligence with Martin Ford Holiday Repeat", + "Episodes Uid": "SED4794020924", + "Episodes Audio File": "41d90ad4a8298caef181862dea8ea564.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2pr", + "Episodes ID": "fb5c445c-e328-11ea-91a2-4b62f066969f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DigitalOwnership.mp3", + "Episodes Pubdate Date": "2017-05-16", + "Episodes Summary": "

When you purchase an ebook you must agree to the Terms of Service that tell you what you can do with it. What is actually in that terms of service? What are you agreeing to when you buy an ebook? The answers might surprise you.

In this episode, Srini Kadamati interviews Chris Groskopf  on how the rise of digital products has eroded the idea of traditional ownership. They discuss digital ownership from the point of view of the legal system, consumers, and the companies creating these products.

Chris Groskopf is a data journalist who uses data, graphics, and storytelling to build compelling news experiences. He’s worked on multiple pioneering teams at organizations like the Chicago Tribune and NPR. He’s currently the first data editor at Quartz, a digital-first Atlantic publication, where he’s written about how complex systems like the stock market fail and how most of the world’s art is locked away in museums. Outside of journalism, he’s created multiple Python data libraries, like agate, proof, and csvkit.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Digital Ownership with Chris Groskopf", + "Episodes Uid": "SED3552372652", + "Episodes Audio File": "4fac2ac7287902bcaf95c9bc22a03a3d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3jn", + "Episodes ID": "f41d733c-e328-11ea-91a2-ff7dcf7a556f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_03_01_ScalingBlockchains.mp3", + "Episodes Pubdate Date": "2018-03-01", + "Episodes Summary": "

There are two factors that limit the rate at which transactions are accepted into the Bitcoin blockchain: block time and block size. Block time defines how often a new block is appended onto the blockchain. Block size defines how many transactions fit into a new block.

As of March 2018, the current block time and block size allow for about 7 transactions per second to be accepted into the Bitcoin blockchain. In today’s episode, we discuss the technical limitations of the Bitcoin blockchain, and some potential solutions to scalability: SegWit and lightning network.

Today’s guest is Peter Ullrich, the host of Explain Blockchain. Explain Blockchain is a podcast I have found tremendously useful as I have started to learn about blockchains. He provides thorough, technical explanations of complicated topics, and I recommend subscribing to his show, and listening to the episodes multiple times, because there is a lot of content condensed into a short amount of time.

Over the next month, we will be exploring a variety of blockchain-based technologies. Some interviews will be high-level conversations that assume only a familiarity with cryptocurrencies. Some of them will be deeply technical, and assume a strong understanding of Bitcoin and Ethereum. And some episodes, like today’s episode, will be aimed at the developer who is in the process of “going down the rabbit hole.”

If you are looking for an internship, apply to the Software Engineering Daily internship, at softwaredaily.com/jobs. And if you are looking to recruit engineers, you can post jobs for your company there as well–it’s completely free to post jobs and to apply. We are hoping to find interns to contribute to the Software Daily open source project–and if you want to see what we are building, go to SoftwareDaily.com or check out our apps in the  iOS or Android app store. They have all 650 of our episodes, with recommendations, related links, discussions and more.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Blockchain Scalability with Peter Ullrich", + "Episodes Uid": "SED1927527702", + "Episodes Audio File": "02c22040fdc39ea09caf819f886be2a3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ob", + "Episodes ID": "f3806dda-e328-11ea-91a2-9f040e53c4a6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_04_16_MonitoringKuberneteswithDatadog.mp3", + "Episodes Pubdate Date": "2018-04-16", + "Episodes Summary": "

Monitoring a Kubernetes cluster allows operators to track the resource utilization of the containers within that cluster. In today’s episode, Ilan Rabinovitch joins the show to explore the different options for setting up monitoring, and some common design patterns around Kubernetes logging and metrics gathering.

Ilan is the VP of product and community at Datadog. Earlier in his career, Ilan spent much of his time working with Linux and taking part in the Linux community. We discussed the similarities and differences between the evolution of Linux and that of Kubernetes.

In previous episodes, we have explored some common open source solutions for monitoring Kubernetes–including Prometheus and the EFK stack. Since Ilan works at Datadog, we explored how hosted solutions compare to self-managed monitoring. We also talked about how to assess different hosted solutions–such as those from a large cloud provider like AWS versus vendors that are specifically focused on monitoring. Full disclosure: Datadog is a sponsor of Software Engineering Daily.

8 Surprising Facts About Real Docker Adoption – Datadog

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Monitoring Kubernetes with Ilan Rabinovitch", + "Episodes Uid": "SED1862923019", + "Episodes Audio File": "9b9fafd1d5762bcda8fbddb2b5398f3e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5gc", + "Episodes ID": "ef04b78e-e328-11ea-91a2-a3e12a6f187c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_13_Cryptojackers.mp3", + "Episodes Pubdate Date": "2019-03-13", + "Episodes Summary": "

Malware is malicious software that makes money for the creator of that software. Malware can appear onto a user’s computer if that user visits a malicious website or installs malicious software by accident.

There are many types of malware. Spyware sits on your machine and logs your data in order to sell it. Ransomware can lock your computer and demand that you pay money to unlock it. Adware serves you popup ads that you don’t want to see.

Cryptojacking is a newer form of malware. Cryptojacking software uses your computer to mine Bitcoin and other cryptocurrencies. Cryptojacking can occur when you visit a website that is running JavaScript that is executing along with the rest of the webpage. When you visit a website with a cryptojacker, your computer will become slower, because your CPU is being taken over to mine cryptocurrency.

Cryptojacking can occur anywhere that code runs–and there is a lot of code running on cloud providers.

Cloud providers themselves are very secure. But a cloud provider cannot force its customers to be secure. Users who host an insecure application on a cloud provider may get infected with a cryptojacker. If I host a large, complex website on a cloud provider, and I’m serving millions of users, I’m already paying a lot in cloud costs. But when my application gets infected with a cryptojacker, my costs could shoot up. And if I don’t know why my costs are increasing, I might leave the cloud provider.

Estaban Vargas is the co-founder of SafeTalpa, a company that provides defense against cryptojackers. Estaban joins the show to explain how cryptojackers work and why cloud providers have trouble defending against them.

", + "Episodes Title": "Cryptojacking: Bitcoin Malware with Estaban Vargas", + "Episodes Uid": "SED8422941179", + "Episodes Audio File": "99618e81abd42c6c2b7068ab25ab9a4a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "xh", + "Episodes ID": "2d2c6192-e329-11ea-91a2-bf9db35b5fce", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/jane_street_Edited.mp3", + "Episodes Pubdate Date": "2015-11-09", + "Episodes Summary": "

Jane Street Capital is a quantitative trading firm known for its emphasis on technology and specifically functional programming. OCaml is the main programming language used at Jane Street, chosen for its performance, correctness and dynamism.

Yaron Minsky is the Head of Technology at Jane Street and was responsible for introducing OCaml to the company and transitioning its architecture.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Automated Trading and OCaml with Yaron Minsky", + "Episodes Uid": "SED2802497367", + "Episodes Audio File": "b0a45e8dd1749eb288721d7f128b9ad2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5ms", + "Episodes ID": "ee67fffc-e328-11ea-91a2-7be74cb198ff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_23_Lightstep_amesBurns.mp3", + "Episodes Pubdate Date": "2019-04-23", + "Episodes Summary": "

RECENT UPDATES:

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

FindCollabs is hiring a React developer

FindCollabs Hackathon #1 has ended! Congrats to ARhythm, Kitspace, and Rivaly for winning 1st, 2nd, and 3rd place ($4,000, $1000, and a set of SE Daily hoodies, respectively). The most valuable feedback award and the most helpful community member award both go to Vynce Montgomery, who will receive both the SE Daily Towel and the SE Daily Old School Bucket Hat

Twilio is a communications infrastructure company with thousands of internal services and thousands of request per second. Each request generates logs, metrics, and distributed traces which can be used to troubleshoot failures and improve latency.

Since Twilio is used for 2-factor authentication and text message relaying, Twilio is critical infrastructure for most applications that implement it. The service must remain highly available even in times of peak application traffic, or outages at a particular cloud provider.

When he was at Twilio, James Burns worked on platform infrastructure and observability. James was at Twilio from 2014 to 2017, a time in which the company experienced rapid scalability. His work encompassed site reliability, monitoring, cost management and incident response. He also led chaos engineering exercises called “game days”, in which the company deliberately caused infrastructure to fail in order to ensure the reliability of failover systems and to discover problematic dependencies.

James joins the show to talk about his time at Twilio and his perspectives on how to instrument and observe complex applications. Full disclosure: James now works at LightStep, which is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Observability Engineering with James Burns", + "Episodes Uid": "SED4007094881", + "Episodes Audio File": "e20563e02bcaf8b3d75f66f410742759.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4y0", + "Episodes ID": "f0850b72-e328-11ea-91a2-2b311d70c815", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_16_Reflow.mp3", + "Episodes Pubdate Date": "2018-11-16", + "Episodes Summary": "

The volume of data in the world is always increasing. The costs of storing that data is always decreasing. And the means for processing that data is always evolving.

Sensors, cameras, and other small computers gather large quantities of data from the physical world around us. User analytics tools gather information about how we are interacting with the Internet. Logging servers collect terabytes of records about how our systems are performing.

From the popularity of MapReduce, to the rise of open source distributed processing frameworks like Spark and Flink, to the wide variety of cloud services like BigQuery: there is an endless set of choices for how to analyze gigantic sets of data.

Machine learning training and inference is another dimension of the modern data engineering stack. Whereas tools like Spark and BigQuery are great for performing ad-hoc queries, systems like TensorFlow are optimized for the model training and deployment process.

Stitching together these tools allows a developer to compose workflows for how data pipelines progress through a data engineering system. One popular tool for this is Apache Airflow, which was created in 2014 and is widely used at companies like Airbnb.

Over the next few years, we will see a proliferation of new tools in the world of data engineering–and for good reason. There is a wealth of opportunity for companies to leverage their data to make better decisions, and potentially to clean and offer their internal data as APIs and pre-trained machine learning models.

Today, there is a vast number of enterprises who are modernizing their software development process with Kubernetes, cloud providers, and continuous delivery. Eventually, these enterprises will improve their complex software architecture, and will move from a defensive position to an offensive one. These enterprises will shift their modernization efforts from “DevOps” to “DataOps”, and thousands of software vendors will be ready to sell them new software for modernizing their data platform.

There is not a consensus for the best way to build and run a “data platform”. Nearly every company we have talked to on the show has a different definition and a different architecture for their “data platform”: Doordash, Dremio, Prisma, Uber, MapR, Snowflake, Confluent, Databricks

We don’t expect to have a concise answer for how to run a data platform any time soon–but on the bright side, data infrastructure seems to be improving. Companies are increasingly able to ask questions about their data and get quick answers, in contrast to the data breadlines that were so prevalent five years ago.

Today we cover yet another approach to large scale data processing.

Reflow is a system for incremental data processing in the cloud. Reflow includes a functional, domain specific language for writing workflow programs, a runtime for evaluating those programs incrementally, and a scheduler for dynamically provisioning resources for those workflows. Reflow was created for large bioinformatics workloads, but should be broadly applicable to scientific and engineering computing workloads.

Reflow  evaluates programs incrementally. Whenever the input data or the program changes, only the outputs that depend on the changes are recomputed. This minimizes the amount of recomputation that needs to be performed across a computational graph.

Marius Eriksen is the creator of Reflow and an engineer at GRAIL. He joins the show to discuss the motivation for a new data processing system–which involves explaining why workloads in bioinformatics are different than in some other domains.

", + "Episodes Title": "Reflow: Distributed Incremental Processing with Marius Eriksen", + "Episodes Uid": "SED1204767146", + "Episodes Audio File": "a250454aa31142e6fd1737fe508c354e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4f3", + "Episodes ID": "f1722e66-e328-11ea-91a2-2bc8eea25ef5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_07_GoToMarket.mp3", + "Episodes Pubdate Date": "2018-09-07", + "Episodes Summary": "

Engineers need to have an awareness of the business model that allows their company to succeed. When a software company is going to market, the engineers need to work closely with the sales and marketing team to formulate a strategy for building and selling that product. This is especially true in highly technical products, such as database- or platform-as-a-service companies.

An engineer at a Hadoop-as-a-service product needs to work with the sales and marketing team to explain why a customer might want a data platform. An engineer at a SaaS company needs to understand how the cost to provide a service might scale, so that the sales team can decide on appropriate pricing.

Mitch Ferguson has been developing businesses at software companies since the 90s. He helped build out SpringSource and arrange the acquisition of SpringSource by VMWare–an acquisition that later enabled the creation of Pivotal Software. He then joined Hortonworks as an early member of the team bringing their Hadoop platform to market.

Today Mitch works as a co-founder of Accel G2M, an organization that helps bring technology companies to market–building out their sales, marketing, product, and organizational strategies.

Accel G2M

", + "Episodes Title": "Go To Market with Mitch Ferguson", + "Episodes Uid": "SED2387116576", + "Episodes Audio File": "f232c6b5ed559d288db42cdc1c29d67c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "39x", + "Episodes ID": "f565997c-e328-11ea-91a2-239d7833f64f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ServerlessSchedulingIBM.mp3", + "Episodes Pubdate Date": "2017-12-04", + "Episodes Summary": "

Functions as a service are deployable functions that run without an addressable server.

Functions as a service scale without any work by the developer. When you deploy a function as a service to a cloud provider, the cloud provider will take care of running that function whenever it is called.

You don’t have to worry about spinning up a new machine and monitoring that machine, and spinning the machine down once it becomes idle. You just tell the cloud provider that you want to run a function, and the cloud provider executes it and returns the result.

Functions as a service can be more cost effective than running virtual machines or containerized infrastructure, because you are letting the cloud provider decide where to schedule your function, and you are giving the cloud provider flexibility on when to schedule the function.

The developer experience for deploying a serverless function can feel mysterious. You send a blob of code into the cloud. Later on, you send a request to call that code in the cloud. The result of the execution of that code gets sent back down to you. What is happening in between?

Rodric Rabbah is the principal researcher and technical lead in serverless computing at IBM. He helped design IBM Cloud Functions, the open source functions-as-a-service platform that IBM has deployed and operationalized as IBM Cloud Functions. Rodric joins the show to explain how to build a platform for functions as a service.

When a user deploys a function to IBM Cloud Functions, that function gets stored in a database as a blob of text, waiting to be called. When the user makes a call to the function, IBM Cloud Functions takes it from the database and queues the function in Kafka, and eventually schedules the function onto a container for execution. Once the function has executed, IBM Cloud Functions stores the result in a database and sends that result to the user.

When you execute a function, the time spent scheduling it and loading it onto a container is known as the “cold start problem”. The steps of executing a serverless function take time, but the resource savings are significant. Your code is just stored as a blob of text in a database, rather than sitting in memory on a server, waiting to execute.

In his research for building IBM Cloud Functions, Rodric wrote about some of the tradeoffs for users who build applications with serverless functions. The tradeoffs exist along what Rodric calls “the serverless trilemma.”

In today’s episode, we discuss why people are using functions-as-a-service, the architecture of IBM Cloud Functions, and the unsolved challenges of building a serverless platform. Full disclosure: IBM is a sponsor of Software Engineering Daily.

OpenWhisk

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Serverless Scheduling with Rodric Rabbah", + "Episodes Uid": "SED6054001009", + "Episodes Audio File": "70f6ae5af5e3fe9fe806bebfee16ec4c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5cv", + "Episodes ID": "ef4f8a48-e328-11ea-91a2-2728524d98cd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_20_Zoox.mp3", + "Episodes Pubdate Date": "2019-02-20", + "Episodes Summary": "

Zoox is a full-stack self-driving car company. Zoox engineers work on everything a self-driving car company needs, from the physical car itself to the algorithms running on the car to the ride hailing system which the company plans to use to drive around riders. Since starting in 2014, Zoox has grown to over 500 employees.

Ethan Dreyfuss is a software infrastructure engineer at Zoox. He joins the show to discuss scaling an engineering team for self-driving. Machine learning was a big part of our conversation, because there are so many different approaches that an engineering team can take when it comes to machine learning for cars.

Can you take computer vision algorithms from academic papers and apply them to cars? Can you use the computer vision APIs from the cloud providers for anything useful? What about physical world mapping companies like Mapillary? How do you do data labeling, and data management? And how do you manage the interactions across the stack, from mechanical engineering to user interface design?

We touched on some of these areas, but barely scratched the surface of the self-driving car domain.

", + "Episodes Title": "Zoox Self-Driving with Ethan Dreyfuss", + "Episodes Uid": "SED4216079093", + "Episodes Audio File": "035d43fe4c10769f563fee4fc13602f5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "32i", + "Episodes ID": "f664a980-e328-11ea-91a2-47188045fb8d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Brave.mp3", + "Episodes Pubdate Date": "2017-09-20", + "Episodes Summary": "

Online advertising enables free content and services of the Internet. One of the free services that is powered by advertising is the browser. 60% of web browsing is done through Chrome, which is owned by Google, which is powered by advertising.

The application that most of us use to explore the web is made by a company that relies on ads, so it is unsurprising that the default of that browser is to allow close tracking of user behavior. When you hit a website, a variety of trackers are logging your data for the purpose of serving you better ads.

Some people don’t like ads, and they don’t like being tracked–but what is the alternative? How else can we get all the content we want? Since the 90’s, engineers have envisioned an Internet powered by micropayments. A micropayments system in your browser would allow users to pay for content with money instead of adtech.

Brave is a web browser built with a modern view of advertising, privacy, and economics. Brave users can pay for content with their money OR by paying attention to ads. This system is formalized through the Basic Attention Token (BAT), a cryptocurrency that can be used to purchase user attention.

Jonathan Sampson is a senior developer relations specialist with Brave Software. He joins the show to talk about the problems with the browsing experience and what Brave is doing to stop it.

", + "Episodes Title": "Brave Browser with Jonathan Sampson", + "Episodes Uid": "SED7778631207", + "Episodes Audio File": "0a2493fd69c305a9c840157c7216ea60.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3d2", + "Episodes ID": "f4f1e496-e328-11ea-91a2-27306d58c05a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/KubernetesUsability.mp3", + "Episodes Pubdate Date": "2018-01-08", + "Episodes Summary": "

Docker was released in 2013, and popularized the use of containers. A container is an abstraction for isolating a well-defined portion of an operating system. Developers quickly latched onto containers as a way to cut down on the cost of virtual machines–as well as isolate code and simplify deployments. Developers began deploying so many containers that they needed a centralized way to manage the containers.     

Then came the rise of the container orchestration framework.

A container orchestration framework is used to manage operating system resources. Twitter had been using the open source orchestration framework Apache Mesos to manage resources since 2010. So when developers started looking for a way to manage containers, many of them chose Mesos. Meanwhile, another container orchestration system came onto the scene: Docker Swarm. Swarm is a tool for managing containers that came from the same people who originally created Docker.

Shortly thereafter, Kubernetes came out of Google. Google had been using containers internally with their cluster manager Borg. Kubernetes is a container orchestration system that was built with the lessons of managing resources at Google.

The reason I recount this history (as I have in a few past episodes) is to underscore that there was a few years where there was a lot of debate around the best container orchestration system to use. Some people preferred Swarm, some preferred Mesos, and some preferred Kubernetes.

Because of the lack of standardization, the community of developers who were building infrastructure in this space were put in a tough position: should you pick a specific orchestration framework, and go all in, building only tools for that one framework? Should you try to build tools to be compatible with all three frameworks, and attempt to satisfy Kubernetes, Mesos, and Swarm users? Or should you sit out altogether and build nothing?

The fracturing of the community led to healthy debates, but it slowed down innovation, because different developers were moving in different directions. Today, the container community has centralized: Kubernetes has become the most popular container orchestration framework.

With the community centralizing on Kubernetes, developers are able to comfortably bet big on open source projects like Istio, Conduit, Rook, Fluentd, and Helm, each of which we will be covering in the next few weeks.

The centralization on Kubernetes also makes it easier to build enterprise companies, who are no longer trying to think about which container orchestration to support. There is a wide array of Kubernetes-as-a-service providers offering a highly available runtime–and a variety of companies offering observability tools to make it easier to debug distributed systems problems.

Despite all of these advances–Kubernetes is less usable than it should be. It still feels like operating a distributed system. Hopefully someday, operating a Kubernetes cluster will be as easy as operating your laptop computer. To get there, we need improvements in Kubernetes usability.

Today’s guest Joe Beda was one of the original creators of the Kubernetes project. He is a founder of Heptio, a company that provides Kubernetes tools and services for enterprises. I caught up with Joe at KubeCon 2017, and he told me about where Kubernetes is today, where it is going, and what he is building at Heptio. Full disclosure–Heptio is a sponsor of Software Engineering Daily.

For the next two weeks, we are covering exclusively the world of Kubernetes. Kubernetes is a project that is likely to have as much impact as Linux. Whether you are an expert in Kubernetes or you are just starting out, we have lots of episodes to fit your learning curve. To find all of our old episodes about Kubernetes, download the Software Engineering Daily app for iOS or for Android. In other podcast players, only the most 100 recent episodes are available, but in our apps you can find all 650 episodes–and there is also plenty of content that is totally unrelated to Kubernetes!

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kubernetes Usability with Joe Beda", + "Episodes Uid": "SED2113643825", + "Episodes Audio File": "fbf0b25b06fec4caa0df49c878d5d620.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5w1", + "Episodes ID": "ed78e110-e328-11ea-91a2-6b58cf7d6cf9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_29_KitspaceRivaly.mp3", + "Episodes Pubdate Date": "2019-06-29", + "Episodes Summary": "

FindCollabs is a platform for finding collaborators and building projects. Three months ago we had our first hackathon, with lots of projects being created and collaborated on. In an earlier episode, we showcased the first place winner ARhythm. 

Today’s show features two more interviews with winners from the first FindCollabs hackathon. Kitspace is an open source hardware registry, and Rivaly is an app for informal ranked leagues, such as ping pong games at work, or board game clubs among your friends.

The second FindCollabs hackathon is going on today. Check it out by going to findcollabs.com/open.

", + "Episodes Title": "FindCollabs Hackathon Winners: Kitspace and Rivaly", + "Episodes Uid": "SED4460992495", + "Episodes Audio File": "74844b192a730f716e6f806e8d8ecd96.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3xf", + "Episodes ID": "f2c7fc1e-e328-11ea-91a2-074fec9080a5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_05_JuliaEvans.mp3", + "Episodes Pubdate Date": "2018-06-05", + "Episodes Summary": "

When software is performing suboptimally, the programmer can use a variety of tools to diagnose problems and improve the quality of the code. A profiler is a tool for examining where a program is spending time.

Every program consists of a set of different functions. These functions call each other. The total amount of time that your program runs is the sum of the time your program spends in all of the different functions. When you run a program, you can execute a profiler on that program, and the profiler will give you a breakdown of which of the different functions time is being spent in.

If you have function A, B, and C, your profiler might say that your program is spending 30% of its time in function A, 20% of its time in function B, and 50% of its time in function C.

Julia Evans is a software engineer at Stripe, and the creator of a Ruby profiler called rbspy. rbspy can execute on a running Ruby program and report back with a profile. As Julia explains, a profiler turns out to be a non-trivial piece of software to build. To introspect a Ruby program, you need to understand how the Ruby interpreter is translating Ruby code into C structs for execution.

This episode is about profilers–but in order to talk about profilers, we also have to talk about Ruby, the Ruby interpreter, and the way that executing programs are laid out in memory.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Profilers with Julia Evans", + "Episodes Uid": "SED6426623607", + "Episodes Audio File": "7bd9062ec5d0f97fe9693b86082e005c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4m4", + "Episodes ID": "f12ac198-e328-11ea-91a2-ab59ebaf3de1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_01_CIinOpenSource.mp3", + "Episodes Pubdate Date": "2018-10-01", + "Episodes Summary": "

Open source software is key to our software infrastructure. Closed source enterprises rely on open source software, but the development processes for closed source and open source software are often different in their approach to continuous integration and delivery.

Oren Novotny is a chief architect of DevOps and modern software at BlueMetal Architects where he works with a variety of clients to build products and internal applications. Oren spends lots of time developing open source software for his job as well as during his spare time. He’s been in the software industry for more than 15 years, and has a wide breadth of insights from different businesses in how they apply software.

We started the conversation talking about electronic trading companies, which in some ways operate like large enterprises and in other ways operate like startups. Oren described working in the financial industry through the 2008 crisis, then switching industries to work at Microsoft, before coming to BlueMetal Architects. We then discussed the process of setting up continuous integration for an open source project–including the difficulties and the large benefits for adding continuous integration to an open source project.

", + "Episodes Title": "Continuous Integration in Open Source with Oren Novotny", + "Episodes Uid": "SED6313455094", + "Episodes Audio File": "63874963c3e44fccd6329cd1e11aac26.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yg", + "Episodes ID": "f6eb1d80-e328-11ea-91a2-d7eac64e170c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Lottie.mp3", + "Episodes Pubdate Date": "2017-08-10", + "Episodes Summary": "

Animations make an application more fun and engaging. For most apps, animation is an afterthought. Developers are concerned with getting the functionality right, and designers have enough work to do simply getting icons, text formatting, and page layout correct.

There is also the issue of cross-device compatibility. iOS, Android, and web have different ways of doing animation, with no unifying standard–except gifs, and gifs are not interactive, they simply play from start to finish.

Airbnb’s emphasis on design makes it the right company to work on the problem of cross-device, interactive animations. Brandon Withrow and Gabriel Peal are engineers who work on Lottie, a library for animations in iOS, Android, web, and React Native.

This episode is about how and why Lottie was built, and how Lottie gets used within Airbnb.

", + "Episodes Title": "Lottie Animation with Brandon Withrow and Gabriel Peal", + "Episodes Uid": "SED4179516468", + "Episodes Audio File": "2e66f832702ba41fa648e0c443dc67eb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "wy", + "Episodes ID": "2d7e0204-e329-11ea-91a2-6bbcc5d31ea4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/haskell_lennart.mp3", + "Episodes Pubdate Date": "2015-11-05", + "Episodes Summary": "

Haskell is a purely functional programming language that employs lazy evaluation.

Lennart Augustsson is a computer scientist who is heavily involved with Haskell, and created the first publicly available Haskell compiler. He is also the author of the Cayenne programming language.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Haskell with Lennart Augustsson", + "Episodes Uid": "SED7020049001", + "Episodes Audio File": "d78729a42813cb24b93727bb6be6900b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 611, + "Episodes ID": "ece6ab06-e328-11ea-91a2-93565dc67c3b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_08_06_DistributedTracingJaeger.mp3", + "Episodes Pubdate Date": "2019-08-06", + "Episodes Summary": "

During 2015, Uber was going through rapid scalability. The internal engineering systems were constantly tested by the growing user base. Over the next two years, the number of internal services at Uber would grow from 500 to 2000, and standardizing the monitoring of all these different services became a priority.

After working with a variety of available tools, Uber’s engineering team decided that something new needed to be built internally. Jaeger is an open source distributed tracing tool that provides observability features throughout Uber’s microservices architecture.

Yuri Shkuro is an engineer at Uber, where he works on Jaeger and other infrastructure projects. He joins the show to discuss the history of engineering at Uber, the architecture of Jaeger, and the requirements for building and scaling a distributed tracing tool.

", + "Episodes Title": "Jaeger: Distributed Tracing at Uber with Yuri Shkuro", + "Episodes Uid": "SED5894065032", + "Episodes Audio File": "d1f1b21485a0b5c6a640d1ec0d81280b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "35y", + "Episodes ID": "f5e86eb0-e328-11ea-91a2-f7a2bbeeec50", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/IFTTT.mp3", + "Episodes Pubdate Date": "2017-10-26", + "Episodes Summary": "

It’s 9pm at night, and you are hungry. You order a pizza from Domino’s. You live on a street that’s dark, and so you have installed a smart lightbulb in front of your mailbox that lights up the address. When the pizza at Domino’s is ready, you want the lightbulb on your mailbox to light up so that the delivery person can read your address when they arrive in front of your house with the pizza.

The Internet should make it possible to have this kind of event-driven, connected world. Anything that is connected to the Internet should be able to send signals to anything else on the Internet, so that our lives gradually become more automated.

This is what IFTTT does. Users of IFTTT can easily create applets to wire different services together. You can use IFTTT to trigger an email whenever three of your friends retweet something on Twitter. You can use IFTTT to flash the lights in your house when Bitcoin hits new market highs. You can use IFTTT to order a pizza whenever Bitcoin crashes.

IFTTT makes it easy to connect different services together, and a lot of work goes into the infrastructure that enables these billions of events to process correctly. Nicky Leach from IFTTT’s engineering team joins the show to describe how IFTTT allows for integrations between services that were not built to integrate–and he talks about the scheduling, data engineering, and monitoring of the company’s software stack.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "IFTTT Architecture with Nicky Leach", + "Episodes Uid": "SED8842076143", + "Episodes Audio File": "cba09f5bbe7259ee894b7cf084e18941.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ho", + "Episodes ID": "0655557e-e329-11ea-91a2-37f0100e77f8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SecureProgramming.mp3", + "Episodes Pubdate Date": "2017-02-23", + "Episodes Summary": "

Security vulnerabilities are an important concern in systems. When we specify that we want certain information hidden, for example our phone number or our date of birth, we expect the system to hide the information. However, this doesn’t always happen due to human error in the code because programmers have to write checks and filters across the program.

In this episode, Edaena Salinas interviews Jean Yang, Assistant Professor at the Computer Science Department at Carnegie Mellon, who presents Jeeves, a language that allows programmers to specify security policies more intuitively, making it harder to leak information that is meant to be protected. Jean explained how Jeeves was implemented and how it can be used. We also talked about what it takes to bring research concepts from academia to the industry and at the end we had a very interesting conversation on how to educate a broader audience on the importance of security. Jean was also named one of the 35 innovators under 35 by MIT Technology Review.

", + "Episodes Title": "Security Language with Jean Yang", + "Episodes Uid": "SED9733545302", + "Episodes Audio File": "9adf7d9ee01e8773957e06f03a58ff8d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 572, + "Episodes ID": "efd9101a-e328-11ea-91a2-a76c9821cdad", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_10_Zeit.mp3", + "Episodes Pubdate Date": "2019-01-10", + "Episodes Summary": "

Serverless computing is a technique for deploying applications without an addressable server.

A serverless application is running on servers, but the developer does not have access to the server in the traditional sense. The developer is not dealing with IP addresses and configuring instances of their different services to be able to scale.

Just as higher level languages like C abstracted away the necessity of a developer to work with assembly code, serverless computing gives a developer more leverage by letting them focus on business logic while a serverless platform takes care of deployment, uptime, autoscaling, and other aspects of cloud computing that are fundamental to every application.

“Serverless” can several different things: backend-as-a-service products like Firebase, functions-as-a-service like AWS Lambda, and high-level APIs such as Twilio.

Zeit is a deployment platform built for serverless development. In Zeit, users model a GitHub repository in terms of the functions within their application. Zeit deploys the code from those functions onto functions-as-a-service and allows you to run your code across all the major cloud providers.

Guillermo Rauch is the founder of Zeit, and he joins the show to discuss his vision for the company and the platform as it looks today. Guillermo was previously on the show to discuss Socket.io, which he created.

", + "Episodes Title": "Zeit: Serverless Cloud with Guillermo Rauch", + "Episodes Uid": "SED3049927563", + "Episodes Audio File": "e1edee965a92e3a08d594ddf4e5b0432.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2qg", + "Episodes ID": "fadb6850-e328-11ea-91a2-d337f33f8d35", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/OscarEngineering.mp3", + "Episodes Pubdate Date": "2017-05-23", + "Episodes Summary": "

Healthcare is a complex business. Oscar is a company that wanted to build a new insurance provider–but realized that healthcare is so interconnected that in order to build a new insurance provider, realized it actually needed to build an entire healthcare business too, complete with patient management and facilities.

Since Oscar is a modern technology company, the focus on customer service, engineering, and data management offers an optimistic view into what healthcare might look like in the near future.

Every time a patient interacts with the healthcare system, their insurance provider collects data on that interaction. Isaac Councill helped architect the infrastructure at Oscar that manages and analyzes the patient data. In this show, we talk about the healthcare system, data engineering, and Apache Mesos, which Oscar uses to manage its applications.

", + "Episodes Title": "Healthcare Engineering with Isaac Councill", + "Episodes Uid": "SED2407918704", + "Episodes Audio File": "7c47d5e1fb7ddfbf90e11db63664e627.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 296, + "Episodes ID": "11fe4732-e329-11ea-91a2-ebc422b28dc4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/githubformusicians_edited.mp3", + "Episodes Pubdate Date": "2016-10-31", + "Episodes Summary": "

Music collaboration software that works over the Internet is a software challenge that has not been fully tackled. On today’s Internet, users collaborate intensively on programming projects, journalism, and other projects, but the tools for collaborating on music online have not yet become popular.

Blend.io is a social music collaboration tool–a github for musicians. I have been using it myself and enjoying it tremendously. Today’s guest Alan Grow joins the show to talk about how to build a social version control system for musicians, as well as where music is headed.

", + "Episodes Title": "Musicians’ GitHub with Alan Grow", + "Episodes Uid": "SED1703572410", + "Episodes Audio File": "fa78ca5b5043d68b6072277a1aa81bad.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 511, + "Episodes ID": "f056a43a-e328-11ea-91a2-ef30436dbaf6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_30_Anchor.mp3", + "Episodes Pubdate Date": "2018-11-30", + "Episodes Summary": "

Podcasts have surged in popularity, but the podcast ecosystem remains difficult to work with. Podcast listeners have difficulty finding episodes. Podcast creators have difficulty finding out how to get started. The advertising marketplaces for podcasts are immature, and it can be difficult to build a business as a podcaster.

Podcasting is unlike almost any other media format that we consume on the Internet. There is not an algorithmic feed of podcasts–we subscribe to podcasts we like and we see everything that gets published. Podcasting originated with Apple, who has not shown much interest in the podcast medium.

Anchor is a platform that makes it easy for users to publish podcasts. Today, a large percentage of the new podcasts created on the Internet are started on Anchor. Nir Zicherman is the CTO at Anchor, and he joins the show to discuss the strange world of podcast technology, and how Anchor is building a business.

", + "Episodes Title": "Anchor: Podcast Platform with Nir Zicherman", + "Episodes Uid": "SED4635643881", + "Episodes Audio File": "f08579c713f9110191c17a79c26a4d2c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5k2", + "Episodes ID": "eea6e41a-e328-11ea-91a2-07575d7e8089", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_05_AWSCompute.mp3", + "Episodes Pubdate Date": "2019-04-05", + "Episodes Summary": "

Upcoming event:

FindCollabs Hackathon at App Academy on April 6, 2019

On Amazon Web Services, there are many ways to run an application on a single node.

The first compute option on AWS was the EC2 virtual server instance. But EC2 is a large abstraction compared to what many people need for their nodes–which is a container with a smaller set of resources to work with. Containers can be run within a managed cluster like ECS or EKS, or run on their own as AWS Fargate instances, or simply as Docker containers running without a container orchestration tool.

Beyond the option of explicit container instances, users can run their application as a “serverless” function-as-a-service such as AWS Lambda. Functions-as-a-service abstract away the container and let the developer operate at a higher level, while also providing some cost savings.

Developers use these different compute options for different reasons. Deepak Singh is the director of compute services at Amazon Web Services, and he joins the show to discuss the use cases and tradeoffs of these options.

Deepak also discusses how these tools are useful internally to AWS. ECS and Lambda are high-level APIs that are used to build even higher level services such as AWS Batch, which is a service for performing batch processing over large data sets.

", + "Episodes Title": "AWS Compute with Deepak Singh", + "Episodes Uid": "SED6397275720", + "Episodes Audio File": "26e4579b2aab30cdd27d8553e9b1cc0f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4xm", + "Episodes ID": "f08e5f60-e328-11ea-91a2-f3abf4443c3b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_11_14_SPIFFE.mp3", + "Episodes Pubdate Date": "2018-11-14", + "Episodes Summary": "

Modern software consists of sprawling international networks of servers.

Users contact these servers to access applications. Microservices talk to each other to fulfill complicated requests. Databases and machine learning frameworks crunch terabytes of information to provide complicated answers. Across this infrastructure, there is a lot of different activities–and a lot of vulnerabilities. Without a reliable model for security and trust, software can be easily compromised.

In the past, systems were often protected by a “firewall”, which is a security system around the perimeter of the network. A problem with this model is that if the attacker is able to penetrate the firewall, they can compromise anywhere in the network. Firewalls can be penetrated, so a much better security model is to assume that your network has already been compromised, and to require every internal system to identify and authenticate with each other.

“Zero-trust security” is a security model that requires internal systems to communicate with each other as if they were potentially compromised. Evan Gilman is the author of Zero Trust Networks: Building Secure Systems in Untrusted Networks. He also works on SPIFFE, a system for managing identity and trust within a zero-trust network.

In a previous episode about Google BeyondCorp, Max Saltonstall talked about zero-trust networking in the context of user and device authentication. In today’s episode, Evan discusses another side of zero-trust networking: workload identity and authentication. Just as Google BeyondCorp outlines an architecture for allowing devices to communicate with the network, the SPIFFE project outlines a system for workloads to identify and authenticate themselves. Workloads can range from MapReduce jobs to microservices to frontend application servers.

", + "Episodes Title": "SPIFFE: Zero Trust Workload Identification with Evan Gilman", + "Episodes Uid": "SED8644447383", + "Episodes Audio File": "3cd6627ad498ebcc7de0e175d9941996.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3g9", + "Episodes ID": "f48daaf8-e328-11ea-91a2-9f1d859b222b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_01_30_DesignPrinciplesforFunctional.mp3", + "Episodes Pubdate Date": "2018-01-30", + "Episodes Summary": "

Functional programming can improve the overall design of an application architecture.

Runar Bjarnason has been exploring how writing in a functional style increases modularity and compositionality of software for many years. He is co-author of Functional Programming in Scala, a book that explores the relationship between functional programming and software design.

In this interview with guest host Adam Bell, Runar explains how writing in a functional style involves limiting side effects, avoiding exceptions and using higher order abstractions. Writing in this style places constraints on what a module in a software system may do, but by constraining modules in this way, the software modules themselves become endlessly composable.  

Functional Programming In Scala

Constraints Liberate, Liberties Constrain

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Design Principles From Functional Programming with Runar Bjarnason", + "Episodes Uid": "SED1702570157", + "Episodes Audio File": "72ef693a37a75b0a78ad46bd811a9339.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "48v", + "Episodes ID": "f1ca90ce-e328-11ea-91a2-875896e41007", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_10_StripeEngineering.mp3", + "Episodes Pubdate Date": "2018-08-09", + "Episodes Summary": "

Stripe is a payments API that allows merchants to transact online. Since the creation of the payments API, Stripe has expanded into adjacent services such as fraud detection, business management, and billing. These other verticals leverage the existing customer base and infrastructure that Stripe has developed from the success of their payments business.

Raylene Yung is the head of payments at Stripe. She joins the show to talk about her work, which includes elements of engineering, product development, design, and management. All of these dimensions of her job came up in our conversation, which made for a wide ranging conversation.

This interview comes in the context of Stripe’s rapid growth. The organization is changing, and Raylene explored the questions that Stripe is asking itself internally about org structure. Namely: what is the tradeoff between a defined, hierarchical structure of direct reports versus a decentralized, flat org structure? Is there any advantage to making roles highly defined (such as “senior infrastructure software engineer”)? Or is it better to let people have fluid roles, and self-assemble?

Raylene was willing to explore these questions–and I found her answers highly useful and thought provoking.

", + "Episodes Title": "Stripe Engineering with Raylene Yung", + "Episodes Uid": "SED6500819222", + "Episodes Audio File": "eac2109abc29772ccdfe0ea989fcbd1e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3ia", + "Episodes ID": "f4465ca2-e328-11ea-91a2-7fd8a33cc86e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_19_TedDunning.mp3", + "Episodes Pubdate Date": "2018-02-19", + "Episodes Summary": "

Streaming architecture defines how large volumes of data make their way through an organization. Data is created at a user’s smartphone, or on a sensor inside of a conveyor belt at a factory. That data is sent to a set of backend services that aggregate the data, organizing it and making it available to business analysts, application developers, and machine learning algorithms.

The velocity at which data is created has led to widespread use of the “stream” abstraction–a never ending, append-only array of data. To deal with this volume, streams need to be buffered, batched, cached, mapreduced, machine learned, and munged until they are in a state where they can provide value to the end user.

There are numerous ways that data can travel this path, and in today’s episode we discuss the streaming systems, data lakes, and data warehouses that can be used to build an architecture that makes use of streaming data. Ted Dunning is a chief application architect at MapR, and he joins the show to discuss the patterns that engineering teams are using to build modern streaming architectures. Full disclosure: MapR is a sponsor of Software Engineering Daily.

Meetups for Software Engineering Daily are being planned! Go to softwareengineeringdaily.com/meetup if you want to register for an upcoming Meetup. In March, I’ll be visiting Datadog in New York and Hubspot in Boston, and in April I’ll be at Telesign in LA.

Summer internship applications to Software Engineering Daily are also being accepted. If you are interested in working with us on the Software Engineering Daily open source project full-time this Summer, send an application to internships@softwareengineeringdaily.com. We’d love to hear from you.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Streaming Architecture with Ted Dunning", + "Episodes Uid": "SED9719741426", + "Episodes Audio File": "cba34527a91d9eb74ee39cb36cf3d270.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2ko", + "Episodes ID": "00e192b0-e329-11ea-91a2-bb07bc0efdc3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Elasticsearch.mp3", + "Episodes Pubdate Date": "2017-04-12", + "Episodes Summary": "

Search is a common building block for applications. Whether we are searching Wikipedia or our log files, the behavior is similar: a query is entered and the most relevant documents are returned. The core data structure for search is an inverted index. Elasticsearch is a scalable, resilient search tool that shards and replicates a search index.

Philipp Krenn from Elastic joins the show today to discuss how search works and how Elasticsearch scales. We use Wikipedia as a running example for how a query is processed and how documents are stored.

If you’ve ever wondered how search works–or if your company uses Elasticsearch and you want to know more about it–this is a great episode for you.

", + "Episodes Title": "Elasticsearch with Philipp Krenn", + "Episodes Uid": "SED3723426598", + "Episodes Audio File": "ff95c17518e2ad663ea5cc286bb08d75.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "ip", + "Episodes ID": "336d1330-e329-11ea-91a2-17b99ee1905c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/christopher_kelly.mp3", + "Episodes Pubdate Date": "2015-09-11", + "Episodes Summary": "

Christopher Kelly is a computer scientist and a pro mountain biker who now works full-time as a health hacker.

He is a co-founder of Nourish Balance Thrive, where he works alongside two medical doctors, a food scientist and a registered nurse to help people feel and perform better using biomedical testing together with diet and lifestyle hacks.

At QCon San Francisco, he will be giving a talk called Debug Me.

", + "Episodes Title": "Health Hacking with Christopher Kelly", + "Episodes Uid": "SED7196976982", + "Episodes Audio File": "e3d9b8ce700411e55718ce21ce9322fb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xi", + "Episodes ID": "ed256e5e-e328-11ea-91a2-b76c5dc37ecc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_17_FacebookDataInfrastructure.mp3", + "Episodes Pubdate Date": "2019-07-17", + "Episodes Summary": "

Facebook generates high volumes of data at a rapid pace.

Dhruba Borthakur joined Facebook in 2008 to work on data infrastructure. His early projects at Facebook were around Hadoop, the distributed file system and MapReduce computation platform that laid the foundation for the “big data” movement. 

At the time, Facebook was generating as much data as any other startup, and the company needed to stay at the leading edge of scalability techniques for its Hadoop Distributed File System (HDFS) cluster. 

Traditionally, Hadoop managed its file system by synchronizing the coordination of the different data nodes with the help of a single master node. At Facebook, the scale of the data was such that the HDFS cluster had thousands of data nodes, which was too much volume for a single master node to handle. Dhruba helped implement redundancy at the master node to create a more resilient system.

The early days of the big data movement was focused on batch processing. A company like Facebook would gather large amounts of data into databases and HDFS, and run offline analytics workloads to gather reports on an hourly, daily, or weekly basis.

Over time, data infrastructure has moved closer to a “real time” processing model. Data infrastructure does not only support batch offline reporting–it also supports machine learning jobs that need to be run on a more frequent basis. These jobs have lower latency requirements, and have driven the adoption of in-memory stream processing systems like Spark and Flink.

Dhruba joins the show to discuss his time at Facebook building data infrastructure. He takes us through the major projects he worked on, including the early Hadoop infrastructure, the refactoring of online user workloads to be more “pull” based than “push” based, and the creation of RocksDB, a storage engine he helped create at Facebook.

Today, Dhruba is the CTO and co-founder of Rockset, a company that builds data infrastructure and database APIs on top of RocksDB. Rockset is building infrastructure for modern technology companies–many of which are facing problems that bear significant resemblance to the ones Facebook encountered as it scaled.

", + "Episodes Title": "Facebook Data Infrastructure with Dhruba Borthakur", + "Episodes Uid": "SED8643807770", + "Episodes Audio File": "f5e30609d86a1fec5fd97d36f69c3284.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3pt", + "Episodes ID": "f328670c-e328-11ea-91a2-8fb9c4366ef3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_05_08_StripeAtlas.mp3", + "Episodes Pubdate Date": "2018-05-08", + "Episodes Summary": "

Starting an Internet business is harder than it should be. You need to incorporate, create an operating agreement, set up a system to accept payments, and many other straightforward tasks.

In the 1990s, this was how it felt to set up anything on the Internet. You always had to stand up a web server on your own infrastructure, before you could get to the interesting part–which was building an actual product. With the popularization of cloud computing, it became massively easier to stand up a server. Because of that lower activation energy, millions of applications and thousands of software businesses got started.

But the activation energy required to start a business remains higher than necessary. It feels like standing up a web server in the 90s–lots of tedium and reinventing the wheel that has been done by people before you. This is the motivation behind Stripe Atlas, a project to simplify the process of starting an Internet business.

Patrick McKenzie works on Atlas at Stripe. He was previously on the show to discuss his experience leaving a large corporation to work on his own small software companies. And his name has become synonymous with the modern phenomenon of the small software company–he has been writing about this topic for over a decade at Kalzumeus.com.

It was great to talk to Patrick once again about Internet businesses, and I’m excited to see Stripe Atlas become something huge.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Stripe Atlas with Patrick McKenzie", + "Episodes Uid": "SED8246716102", + "Episodes Audio File": "0598856f8ff5ae45abcd8b331a50fbd0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3d4", + "Episodes ID": "f4e76908-e328-11ea-91a2-a387198279e5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/KubernetesonAWS.mp3", + "Episodes Pubdate Date": "2018-01-10", + "Episodes Summary": "

Since Kubernetes came out, engineers have been deploying clusters to Amazon. In the early years of Kubernetes, deploying to AWS meant that you had to manage the availability of the cluster yourself. You needed to configure etcd and your master nodes in a way that avoided having a single point of failure.

Deploying Kubernetes on AWS became simpler with an open-source tool called kops (short for Kubernetes Operations). Kops automates the provisioning and high-availability deployment of Kubernetes.

In late 2017, AWS released a managed Kubernetes service called EKS. EKS allows developers to run Kubernetes without having to manage the availability and scaling of a cluster. The announcement of EKS was exciting, because it means that all of the major cloud providers are officially supporting Kubernetes.

Arun Gupta is a principal open source technologist at AWS, and he joins the show to explain what is involved in deploying and managing a Kubernetes cluster. Arun describes how to operate a Kubernetes cluster, including logging, monitoring, storage, and updates. If you are convinced that you want to use Kubernetes, but you aren’t sure yet how you want to deploy it, this will be useful information for you.

We also discussed how Amazon built EKS, and some of the architectural decisions they made. AWS has had a managed container service called ECS since 2014. The development of ECS was instructive for the AWS engineers who built EKS. Amazon wanted to make EKS able to integrate with both open source tools and the Amazon managed services.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Kubernetes on AWS with Arun Gupta", + "Episodes Uid": "SED9604833344", + "Episodes Audio File": "6ef5653f24c1c34007feed48cdc0ac0d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5lz", + "Episodes ID": "ee7c0678-e328-11ea-91a2-f706b3d620c1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_04_17_Drishti.mp3", + "Episodes Pubdate Date": "2019-04-17", + "Episodes Summary": "

RECENT UPDATES:

Podsheets is our open source set of tools for managing podcasts and podcast businesses

New version of Software Daily, our app and ad-free subscription service

Software Daily is looking for help with Android engineering, QA, machine learning, and more

FindCollabs Hackathon has ended–winners will probably be announced by the time this episode airs; we will be announcing our next hackathon in a few weeks, so stay tuned

Drishti is a company focused on improving manufacturing workflows using computer vision.

A manufacturing environment consists of assembly lines. A line is composed of sequential stations along that manufacturing line. At each station on the assembly line, a worker performs an operation on the item that is being manufactured. This type of workflow is used for the manufacturing of cars, laptops, stereo equipment, and many other technology products.

With Drishti, the manufacturing process is augmented by adding a camera at each station. Camera footage is used to train a machine learning model for each station on the assembly line. That machine learning model is used to ensure the accuracy and performance of each task that is being conducted on the assembly line.

Krish Chaudhury is the CTO at Drishti. From 2005 to 2015 he led image processing and computer vision projects at Google before joining Flipkart, where he worked on image science and deep learning for another four years. Krish had spent more than twenty years working on image and vision related problems when he co-founded Drishti.

In today’s episode, we discuss the science and application of computer vision, as well as the future of manufacturing technology and the business strategy of Drishti.

", + "Episodes Title": "Drishti: Deep Learning for Manufacturing with Krish Chaudhury", + "Episodes Uid": "SED7304310172", + "Episodes Audio File": "9e6c27a8223cd70ec88b51e55a46d27f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "36r", + "Episodes ID": "f5c5a416-e328-11ea-91a2-17c40c4ae67d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/PaulMartino.mp3", + "Episodes Pubdate Date": "2017-11-03", + "Episodes Summary": "

In 2003, Paul Martino co-founded Tribe.net, one of the earliest social networking sites.  Tribe had significant traction, with hundreds of thousands of users.

In the early 2000s, hundreds of thousands of users was enough traffic to pose a company with engineering challenges. Paul had studied computer science, and was able to use his knowledge of high-performance computing to write an efficient graph database, and solve the other technical puzzles that the company faced–but the business did not ultimately work out.

The failure of Tribe made the founders even hungrier for success–and it taught them lessons that they carried into subsequent businesses.

Paul went on to start Aggregate Knowledge, a marketing technology company that sold for $119 million. His Tribe co-founder Mark Pincus went on to start Zynga, the multi-billion dollar gaming company. Another Tribe employee co-founded Yammer, which sold to Microsoft for a billion dollars.

Since his exit from Aggregate Knowledge, Paul Martino started Bullpen Capital, which makes post-seed investments. The Bullpen Capital portfolio is appealing to me–partly because of the number of Internet gambling companies. Paul and I talked about gambling and other taboo business sectors–as well as what makes a good investment in the “post-seed” category.

I enjoyed speaking to Paul because he has a straightforward, no-nonsense way of talking about things–it’s very charismatic and uncommon.

We have done some great shows with other engineering investors like Chris Dixon and Adrian Colyer. To find these old episodes, you can download the Software Engineering Daily app for iOS and for Android. In other podcast players, you can only access the most recent 100 episodes. With these apps, we are building a new way to consume content about software engineering. They are open-sourced at github.com/softwareengineeringdaily. If you are looking for an open source project to get involved with, we would love to get your help.

Shout out to today’s featured contributor Kurian Vithayathil. He has made significant contributions to the Software Engineering Daily Android app. Thanks again Kurian for your work.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Parlaying Failure to Fortune with Paul Martino", + "Episodes Uid": "SED6792408378", + "Episodes Audio File": "efd8ff4edbe7a301dff7334d4a74ba75.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2x5", + "Episodes ID": "f719556a-e328-11ea-91a2-a7495bab9b80", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/SelfDrivingDeepLearning.mp3", + "Episodes Pubdate Date": "2017-07-28", + "Episodes Summary": "

Self-driving cars are here. Fully autonomous systems like Waymo are being piloted in less complex circumstances. Human-in-the-loop systems like Tesla Autopilot navigate drivers when it is safe to do so, and lets the human take control in ambiguous circumstances.

Computers are great at memorization, but not yet great at reasoning. We cannot enumerate to a computer every single circumstance that a car might find itself in. The computer needs to perceive its surroundings, plan how to take action, execute control over the situation, and respond to changing circumstances inside and outside of the car.

Lex Fridman has worked on autonomous vehicles with companies like Google and Tesla. He recently taught a class on deep learning for semi-autonomous vehicles at MIT, which is freely available online. There was so much ground to cover in this conversation. Most of the conversation was higher level. How do you even approach the problem? What is the hardware and software architecture of a car?

I enjoyed talking to Lex, and if you want to hear more from him check out his podcast Take It Uneasy, which is about jiu jitsu, judo, wrestling, and learning.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Self-Driving Deep Learning with Lex Fridman", + "Episodes Uid": "SED2871275884", + "Episodes Audio File": "74af0314f9058aedf8c7e21256de91bb.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 551, + "Episodes ID": "f008276a-e328-11ea-91a2-7fba5584f1a5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/googleearlydays_edited.mp3", + "Episodes Pubdate Date": "2018-12-25", + "Episodes Summary": "

Originally posted on 16 June 2017.

John Looney spent more than 10 years at Google. He started with infrastructure, and was part of the team that migrated Google File System to Colossus, the successor to GFS. Imagine migrating every piece of data on Google from one distributed file system to another.

In this episode, John sheds light on the engineering culture that has made Google so successful. He has very entertaining stories about clusterops and site-reliability engineering.

Google’s success in engineering is due to extremely high standards, and a culture of intellectual honesty. With the volume of data and throughput that Google responds to, 1-in-a-million events are likely to occur. There isn’t room for sloppy practices.

John now works at Intercom, where he is adjusting to the modern world of Google infrastructure for everyone. This conversation made me feel quite grateful to be an engineer in a time where everything is so much cheaper, so much easier, and so much more performant than it was in the days when Google first built everything from scratch.

I had a great time talking to John, and hope he comes back on the show again in the future because it felt like we were just scratching the surface of his experience.

", + "Episodes Title": "Google Early Days with John Looney Holiday Repeat", + "Episodes Uid": "SED6920312701", + "Episodes Audio File": "9afbad2deaa51095fc58d9116fe631ad.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "41o", + "Episodes ID": "f27ad59c-e328-11ea-91a2-afc59d9fc7d4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_06_26_FaaSonKubernetes.mp3", + "Episodes Pubdate Date": "2018-06-26", + "Episodes Summary": "

“Serverless” is a word used to describe functions that get deployed and run without the developer having to manage the infrastructure explicitly.

Instead of creating a server, installing the dependencies, and executing your code, the developer just provides the code to the serverless API, and the serverless system takes care of the server creation, the installation, and the execution. Serverless was first offered with the AWS Lambda service, but has since been offered by other cloud providers.

There have also been numerous open source serverless systems. On SE Daily, we have done episodes about OpenWhisk, Fission, and Kubeless. All of these are built on the Kubernetes container management system. Kubernetes is an open-source tool used to build and manage infrastructure, so it is a useful building block for higher level systems.

Chad Arimura is the VP of serverless at Oracle, where he runs the Fn project, an open source serverless platform built on top of Kubernetes. In the past, he ran Iron.io, a message broker platform. Matt Stephenson also joins the show–he is a senior principal software engineer at Oracle and has experience from Amazon and Google, where he worked on Google App Engine (which was arguably one of the first “serverless” platforms).

We discussed why there are so many different serverless tools built on Kubernetes, and the tradeoffs that these serverless tools are exploring.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Function Platforms with Chad Arimura and Matt Stephenson", + "Episodes Uid": "SED7536533743", + "Episodes Audio File": "85a135c43535c830f474ed51ec0f2551.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4d2", + "Episodes ID": "f1847936-e328-11ea-91a2-ffd50989ba58", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_31_RideOS.mp3", + "Episodes Pubdate Date": "2018-08-31", + "Episodes Summary": "

Self-driving transportation will be widely deployed at some point in the future. How far off is that future? There are widely varying estimations: maybe you will summon a self-driving Uber in a New York within 5 years, or maybe it will take 20 years to work out all of the challenges in legal and engineering.

Between now and the self-driving future, there will be a long span of time where cars are semi-autonomous. Maybe your car is allowed to drive itself in certain areas of the city. Maybe your car can theoretically drive itself in 99% of conditions, but the law requires you to be behind the wheel until the algorithms get just a little bit better.

While we wait for self-driving to be widely deployed to consumers, a lot could change in the market. We know about Uber, Lyft, Waymo, Tesla and Cruise. But what about the classic car companies like Ford, Mercedes Benz, and Volkswagen? These companies are great at making cars, and they have hired teams of engineers working on self-driving.

But self-driving functionality is not the only piece of software you need to compete as a transportation company. You also need to build a marketplace for your autonomous vehicles, because in the future, far fewer people will want to own a car. Customers will want to use transportation as a service.

RideOS is a company that is building fleet management and navigation software. If you run a company that is building autonomous cars, you need to solve the problem of making an autonomous, safe robot that can drive you around.

Building an autonomous car is hard, but to go to market as a next-generation transportation company, you also need fleet management software, so you can deploy your cars in an Uber-like transportation system. And you need navigation software so that your cars know how to drive around.

RideOS lets a car company like Ford focus on building cars by providing a set of SDKs and cloud services for managing and navigating fleets of cars. Rohan Paranjpe joins today’s show to talk about the world of self-driving cars. Rohan worked at Tesla and Uber before joining RideOS, so he has a well-informed perspective on a few directions the self-driving car market might go in.

", + "Episodes Title": "RideOS: Fleet Management with Rohan Paranjpe", + "Episodes Uid": "SED6431611530", + "Episodes Audio File": "b2cc2488ecb638786457da453f100b7a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2x6", + "Episodes ID": "f713b57e-e328-11ea-91a2-6f1fecbfa399", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/HealthWearables.mp3", + "Episodes Pubdate Date": "2017-07-31", + "Episodes Summary": "

Wearables are everywhere. In the medical field they are transforming lives. Haiyan Zhang, Innovation Director at Microsoft Research, created a wearable for a young graphic designer that developed Parkinson’s. Parkinson’s is a condition that inhibits movement, and this wearable allows the Parkinson’s patient to write and draw again. Haiyan explained the research process and the technical aspects of how it works.

Edaena Salinas of The Women in Tech Show interviewed Haiyan for this episode. They talked about the Internet of Things, the components of these systems and the technical challenges. Haiyan also explained her path from software engineering to design and the process of commercializing products that come from research.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Health Wearables with Haiyan Zhang", + "Episodes Uid": "SED1965613661", + "Episodes Audio File": "7f832ce8f2bb9889ab3ce6891be61106.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2yp", + "Episodes ID": "f6b9e756-e328-11ea-91a2-ab723dc178ee", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/AIExtremism.mp3", + "Episodes Pubdate Date": "2017-08-25", + "Episodes Summary": "

Religious extremists use technology to recruit vulnerable individuals to a violent cause. Google is developing ways to combat this extremism through its platforms, namely YouTube. When a user looks for inflammatory religious or supremacist content, YouTube’s “Redirect Method” instead sends those users toward anti-terrorist videos.

Google’s fight against extremism compelled writer Lochlan Bloom to write an article called “The Coming Battle: AI, Extremism, and the New War of Ideas.” Lochlan joins the show to discuss the societal implications of giant internet providers controlling our information flow.

Lochlan is a science fiction writer, most recently of The Wave, a book that mixes existentialism with quantum physics. Our reality is defined by what we observe, and this theme courses through our conversation–from religion to Twitter to artificial intelligence.

The Coming Battle: AI, Extremism, and the New War of Ideas

", + "Episodes Title": "Internet Extremism with Lochlan Bloom", + "Episodes Uid": "SED8014247607", + "Episodes Audio File": "051774afbc3620142c4ea492c91a6257.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "vn", + "Episodes ID": "2e21f1a2-e329-11ea-91a2-93ddc49db85a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/zipfian_post_gband_2.mp3", + "Episodes Pubdate Date": "2015-10-29", + "Episodes Summary": "

Galvanize Data Science is a 12-week data science program born out of Zipfian Academy, which was acquired by Galvanize in 2014.

Jonathan Dinu and Ryan Orban were the founders of Zipfian, and are now continuing their work to teach data science at Galvanize.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Galvanize Data Science with Jonathan Dinu and Ryan Orban", + "Episodes Uid": "SED5031383390", + "Episodes Audio File": "6df9104a8b2880c197618e4469b871be.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2mo", + "Episodes ID": "fec7f26c-e328-11ea-91a2-1fe5b5b52c96", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ezanga.mp3", + "Episodes Pubdate Date": "2017-04-25", + "Episodes Summary": "

The online advertising industry is a giant casino. Giant technology companies are the casino owners, online publishers are the casino employees, the brand advertisers are the victims who keep returning to the casino to lose their money, and the small adtech companies are the sharks who make lots of money exploiting the inefficiencies of the system.

One of these smaller adtech companies is called eZanga. eZanga sells “pre-filtered traffic.” Pre-filtered traffic means traffic that will pass through bot detection filters. A publisher  can purchase traffic to their website so that the ads on that website get viewed.

eZanga describes this technology as “marketing,” and has won a giant contract with United States government to handle advertising for the GSA. Advertising fraud does not just promote misinformation–it is now taking our tax dollars and spending it on paid traffic.

If any of this is confusing to you, don’t worry. We explain it all in today’s episode with Shailin Dhar, the advertising fraud expert who wrote a detailed report about eZanga and its contract with the US Government. Shailin was previously on the show to give an overview of ad fraud, and what his work as an ad fraud investigator entails.

Also, Shailin will be a speaker at our third Meetup, Wednesday May 3rd at Galvanize in San Francisco. The theme of this Meetup is Fraud and Risk in Software. We will have great food, engaging speakers, and a friendly, intellectual atmosphere. To find out more, go to softwareengineeringdaily.com/meetup.

Ad Fraud in Our Own Backyard: The Dhar Method

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to download the eZanga transcript.

", + "Episodes Title": "Ad Fraud In Our Own Backyard with Shailin Dhar", + "Episodes Uid": "SED5733686034", + "Episodes Audio File": "0e7a5478b17b345727ab0670afbc540e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4d0", + "Episodes ID": "f18e0c94-e328-11ea-91a2-63b57f8fc6a8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_29_DataKitchen.mp3", + "Episodes Pubdate Date": "2018-08-29", + "Episodes Summary": "

Every company with a large set of customers has a large set of data–whether that company is 5 years old or 50 years old. That data is valuable whether you are an insurance company, a soft drink manufacturer, or a ridesharing company. All of these large companies know that their data is valuable, but some of them are not sure how to standardize the access patterns of that data, or build a culture around data.

The larger the company is, the more the data is spread throughout the company, and the more heterogeneous the data sources are. Older companies often have older pieces of data infrastructure, and it might not be well documented.

It is hard to make data driven decisions when an organization cannot effectively query their own data. For example, consider a simple question about marketing. An insurance company wants to know how their spending on TV advertising correlates with sales in California over the last 25 years.

The VP of marketing sends an email to a business analyst, asking for a historical report of this marketing data. The business analyst knows how to present the data with a business intelligence tool, but the analyst needs to ask the data scientist for how to make that query. The data scientist needs to ask the data engineer where to find those records in a large Hadoop distributed file system cluster. And the data engineer joined the company last week and has no idea where anything is.

These are the problems of DataOps. Similarly to DevOps, DataOps is the recognition that a set of problems have crept into organizations over time and slowed down productivity.

The story of the DevOps movement is that old infrastructure, lack of testing, and complicated monolithic backends slowed down everyone in an old, big enterprise. The slow pace of change destroys morale and erodes trust. The DevOps movement is about revamping organizations through tooling and organizational behavior. We have covered this in lots of episodes, such as in a great episode with Gene Kim who wrote “The Phoenix Project.”

When an organization wants to reinvent itself with DevOps, it often begins with testing and continuous delivery. DataOps encourages data driven organizations to begin with a similar practice of testing their data pipelines to build trust and evolve best practices. There are other similarities between DataOps and DevOps, such as continuous delivery and the breaking down of siloes between different organizational roles.

Chris Bergh joins the show to talk about the data problems encountered by large companies, the practices of DataOps, and his company Data Kitchen, which builds tools to help companies move towards more productive data practices.

", + "Episodes Title": "DataOps with Christopher Bergh", + "Episodes Uid": "SED6436865129", + "Episodes Audio File": "0311abff89b931c481f3be9a07633731.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2hd", + "Episodes ID": "06aee8be-e329-11ea-91a2-0fac0db5bada", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/AIwithRobMay.mp3", + "Episodes Pubdate Date": "2017-02-20", + "Episodes Summary": "

The impact of artificial intelligence on our everyday lives will be so profound that our modern institutions will change completely. Employment, government, romance, social norms–all of these things will be upended. To see the signs of this coming, you no longer have to read science fiction. Every week, there are blog posts, news stories, and videos chronicling our strange, exciting time.

Rob May is an investor in artificial intelligence companies and is CEO of the AI company Talla. Every week, he puts out the Technically Sentient newsletter, a compilation of the best pieces of information about AI over the past week. Each newsletter also contains a short essay by Rob in which he gives a big picture perspective on what he is seeing in the AI space.

This was an illuminating conversation with Rob about the implications of artificial intelligence and the topics he writes about in Technically Sentient.

I first saw Rob speak at the Launch Scale Festival, which Jason Calacanis puts on as a free event for people who have started companies.

", + "Episodes Title": "Technically Sentient with Rob May", + "Episodes Uid": "SED3102629408", + "Episodes Audio File": "75a357137a10a82c0d0e9d19403907a9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "57i", + "Episodes ID": "efd3fca6-e328-11ea-91a2-8bacbc38a286", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_01_11_CoreyQuinn.mp3", + "Episodes Pubdate Date": "2019-01-11", + "Episodes Summary": "

Amazon Web Services changed how software engineers work. Before AWS, it was common for startups to purchase their own physical servers. AWS made server resources as accessible as an API request, and has gone on to create higher-level abstractions for building applications.

For the first few years of AWS, the abstractions were familiar. S3 provided distributed, reliable object storage. Elastic MapReduce provided a managed Hadoop system. Kinesis provided a scalable queue. Amazon provided developers with managed alternatives to complicated open source software.

More recently, AWS has started to release products that are unlike anything else. A perfect example is AWS Lambda, the first function-as-a-service platform. Other newer AWS products include Ground Station, a service for processing satellite data and AWS DeepRacer, a miniature race car for developers to build and test machine learning algorithms on.

As AWS has grown into new categories, the blog announcements of new services and features have started coming so frequently that it is hard to keep track of it all. Corey Quinn is the author of “Last Week in AWS”, a popular newsletter about what is changing across Amazon Web Services.

Corey joins the show to give his perspective on the growing, shifting behemoth that is Amazon Web Services–as well as the other major cloud providers that have risen to prominence. He’s also the host of the Screaming in the Cloud podcast, which you should check out if you like this episode.

", + "Episodes Title": "AWS Analysis with Corey Quinn", + "Episodes Uid": "SED7723853960", + "Episodes Audio File": "c76212488c1051d46d3ea4b70f9c08c2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4dv", + "Episodes ID": "f17f604a-e328-11ea-91a2-abccc9e16232", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_09_04_Jaspersoft.mp3", + "Episodes Pubdate Date": "2018-09-04", + "Episodes Summary": "

TIBCO was started in the 90’s with a popular message bus product that was widely used by finance companies, logistics providers, and other systems with high throughput. As TIBCO grew in popularity, the company expanded into other areas through products it developed in-house as well as through acquisitions.

One acquisition was Jaspersoft, a business intelligence data platform. When TIBCO acquired Jaspersoft in 2014, the architecture was a monolithic Java application. Around this time, customer use cases were shifting from centralized reporting to real-time, embedded visualizations.

The use case of the Jaspersoft software was becoming less centralized and less monolithic and the software architecture needed to change in order to reflect that.

Jan Schiffman is a VP of engineering at TIBCO and Sherman Wood is a director at TIBCO. They join the show to discuss the process of migrating a large Java monolith to a composable set of services. Breaking up a monolith is not an easy process–nor is it something that every company should do just because they have a monolith. In some cases, a monolith is just fine.

Jan and Sherman explain why the business use case for why the Jaspersoft monolith needed to be refactored, and their approach to the refactoring. We also talk through the modern use cases of embedded analytics and the interaction between business analysts and data engineers. At a higher level, we discuss the lessons they have learned from managing a large, complex refactoring. Full disclosure: TIBCO is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Monolith Migration with Jan Schiffman and Sherman Wood", + "Episodes Uid": "SED2540568188", + "Episodes Audio File": "d941a52b86f4c56e625b7abbbb92400a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2jv", + "Episodes ID": "02ff272e-e329-11ea-91a2-bf99c18de3c1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Invision.mp3", + "Episodes Pubdate Date": "2017-03-28", + "Episodes Summary": "

Designers and software engineers need to communicate with each other. From Apple to Slack to Uber, the emphasis on visual design within a product is rising in importance. Much like development and operations siloes have been bridged with the DevOps movement, design and engineering teams are working more closely together to align the vision of the designers with the realities of code.

InVision is a product for prototyping designs and product workflows. I categorize InVision with high-level productivity tools like Trello, Asana, and github. When teams start using InVision, it often becomes an integral part of the entire product workflow. A designer will mock up their product vision on InVision and share it with the rest of the team for criticism and commentary.

Since the product is the perfect bridge between engineers and designers, InVision the company is expanding as a platform. Bjorn Freeman-Benson is the CTO at InVision and his task is to scale the 100% remote engineering team while developing new product features.

Bjorn describes himself as a software psychologist. We talked about the psychology of managing engineers and the technical challenges of building a large, popular web app for technology products.

", + "Episodes Title": "Software Psychology with Bjorn Freeman Benson", + "Episodes Uid": "SED6431667989", + "Episodes Audio File": "e0f9d05c626cb8d8fb44992cc8bdb12b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "49p", + "Episodes ID": "f1d88436-e328-11ea-91a2-33fd5250533d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_08_06_Splice-io.mp3", + "Episodes Pubdate Date": "2018-08-06", + "Episodes Summary": "

Music collaboration has historically been accomplished by musicians gathering in bands. A band is usually an in-person, physical manifestation: a drummer, a guitarist, a piano player. Or, on a large scale, a symphony of classical instruments led by a conductor. Today, the most flexible instrument that anyone can play is arguably the computer, because a computer can simulate or replay any of the sounds made by any other instrument.

Another advantage of the computer is that it removes physicality as a constraint on the musician. A computer musician does not have to train their muscles to play piano, or guitar, or drums. The computer musician can imagine a sound and bring it to life inside a digital audio workstation (a program for composing and arranging music).

The rise of the computer musician has coincided with a change in the way popular music is created. Instead of bands needing to work together to create a piece of music, a single producer can simulate all of the members of the band by programming piano, drums, and everything else.

The rise of the solo producer has given birth to new kinds of music–but solo music production inherently limits the range of musical ideas that can be explored. The most important works of art have input from multiple people. And even the most successful solo producers love to work with other artists who have a complementary skill–such as vocals.

For the last twenty years, the model of solo producer working with pop vocalist has largely dominated the charts. Musical collaboration has stuck to a model that mimics its pre-Internet form, with very small groups of 1-5 people making the core of a song. The main tools that people use to collaborate are email and Dropbox.

Splice is a tool for music collaboration. Splice combines version control, revision history, social networking, sample discovery, synthesizer rental, and other features. Splice is changing the way that music is created, with a large percentage of top producers adopting it. The impact Splice has on music will be on par with what Github has done for software engineering.

Matt Aimonetti is the CTO and co-founder of Splice, and he joins the show to talk about the founding story, the product development, and the engineering of Splice.

", + "Episodes Title": "Splice: Music Collaboration with Matt Aimonetti", + "Episodes Uid": "SED3201732369", + "Episodes Audio File": "f8215a43b426647d1a30f4b8e07960d4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xd", + "Episodes ID": "ed53c9fc-e328-11ea-91a2-b3700f4f698a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_10_Gvisor2.mp3", + "Episodes Pubdate Date": "2019-07-10", + "Episodes Summary": "

Software applications running within a host operating system need to be isolated. Isolation prevents security vulnerabilities, such as one application accessing the memory of another.

In modern cloud environments, a single physical host might be running multiple virtual machines on top of a hypervisor. Those virtual machines might be divided up into containers. The different virtual machines and containers might be operated by different users, or even different companies.

gVisor is a container sandbox runtime open sourced by Google. gVisor runs containers in a new user-space kernel, and provides a container security system with low overhead. gVisor improves on the previous security properties of containers.

Michael Pratt and Yoshi Tamura work on gVisor at Google, and they join the show to talk through the purpose of gVisor and the engineering around the project.

", + "Episodes Title": "gVisor Container Isolation with Michael Pratt and Yoshi Tamura", + "Episodes Uid": "SED4698538812", + "Episodes Audio File": "b61e003130acb34535d0272530243cbe.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2oy", + "Episodes ID": "fc59db6c-e328-11ea-91a2-83ad6eaeaa49", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/roundtable_edited.mp3", + "Episodes Pubdate Date": "2017-05-08", + "Episodes Summary": "

Suddenly, automation is changing our world faster than anyone anticipated. For technologists, the world is becoming convenient and high-leverage. For non-technologists, the job market is evaporating.

Haseeb Qureshi and Quincy Larson join me for a roundtable discussion on automation, jobs, and artificial intelligence. Haseeb and I have had numerous discussions about this topic before, and Quincy is the founder of Free Code Camp, which teaches people to learn programming for free. If there is one upside of all these jobs being automated away, its that it will lead to massive user growth for Free Code Camp.

I enjoyed talking to Quincy and Haseeb as always.

If you are interested in hosting a show for Software Engineering Daily, we are looking for engineers, journalists, and hackers who want to work with us on content. It is a paid opportunity. Go to softwareengineeringdaily.com/host to find out more.

The Software Engineering Daily store is now open if you want to buy a Software Engineering Daily branded t-shirt, hoodie, or mug and support the show. Let’s get on with the show. Go to softwareengineeringdaily.com/store.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Automation with Haseeb Qureshi and Quincy Larson", + "Episodes Uid": "SED6717374665", + "Episodes Audio File": "ffdd7d1e2bfc37d85171371f4adcd426.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2t2", + "Episodes ID": "f9627446-e328-11ea-91a2-7fc030ad5af7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/datateams_edited.mp3", + "Episodes Pubdate Date": "2017-06-15", + "Episodes Summary": "

A data-driven organization is more efficient because the company can learn what to focus on. In this episode, Edaena Salinas from The Women in Tech Show interviews Rya Sciban, Product Manager at Periscope Data, who explains the needs of data teams in an organization. We talked about what data analysis is and how this changes as the amount of data grows. Rya explained what analytics clusters are and effective ways of sharing data between the organization.

Periscope Data has been successful in retaining women in product and development teams. We talked about effective strategies for this and for having more women in leadership positions.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Data Teams with Rya Sciban", + "Episodes Uid": "SED1299969182", + "Episodes Audio File": "17f07f5535b841674455608bf30e244d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5bh", + "Episodes ID": "ef6ec94e-e328-11ea-91a2-37625713441c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_02_11_Pachyderm.mp3", + "Episodes Pubdate Date": "2019-02-11", + "Episodes Summary": "

Data infrastructure is advancing beyond the days of Hadoop MapReduce, single-node databases, and nightly reporting.

Companies are adopting modern data warehouses, streaming data systems, and cloud-specific data tools like BigQuery. Every company with a large amount of data wants to aggregate that data into a data lake and make the data available to developers. All of this data can be used to power machine learning models which can potentially improve every area within a company where they have historical data.

“Data pipeline” is a term used to describe the process of preparing data, building machine learning models, deploying those models, and tracking the results of those models.

Pachyderm is a company and open source project that is focused on deployment, management, and scalability of data pipelines. Pachyderm allows developers to version data, track the state of data sets, backtest machine learning models, and collaborate on data. It also tackles the very hard problem of machine learning auditability.

Joe Doliner is the CEO of Pachyderm and joins the show to discuss his experience building Pachyderm over the last five years. Data infrastructure has changed a lot in five years, and the world has moved in a direction that has benefitted Pachyderm, with more infrastructure moving to containers and more data teams advancing beyond a world of just Hadoop MapReduce.

In today’s show, Joe talks about modern infrastructure, data provenance, and the long-term vision of Pachyderm.

", + "Episodes Title": "Pachyderm: Data Pipelines with Joe Doliner", + "Episodes Uid": "SED8004313725", + "Episodes Audio File": "d16951da96eea8882c2615928b424681.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4r1", + "Episodes ID": "f0eb8f3c-e328-11ea-91a2-a3845811341a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_10_18_ProductStrategy.mp3", + "Episodes Pubdate Date": "2018-10-18", + "Episodes Summary": "

Linux has created much more value for Google than it has for Linus Torvalds. Ruby on Rails has created more value for Airbnb than it has for David Heinemeier Hansson. Successful open source projects create more value than their creators’ capture–and that’s one reason why collections of people on the Internet are often inspired to work together on open source.

When an engineer creates an open source project, and that open source project finds a large audience, that engineer can often build a successful business. SpringSource, Cloudera, and Elastic are examples of massively successful enterprises that were founded by the creators of open source software. But in other cases, the value of an open source project gets largely captured by cloud providers that create a closed source version of the open source project and offer it as a service.

Shaun Connolly has worked in senior strategic roles at software companies such as SpringSource, VMWare, and Hortonworks. Throughout his decades of experience, much of his time has been spent figuring out how to monetize open source projects intelligently. Shaun joins the show to talk about his past experiences building enterprises, as well as modern issues–such as how to compete with major cloud providers. We also discuss the Commons Clause license, a new software license that open source projects can use to try to protect their value from being entirely captured by a cloud provider.

Software Engineering Daily is looking for sponsors. If you are interested in reaching over 50,000 developers, you can go to softwareengineeringdaily.com/sponsor to find out more, and you can send us a message. We’d love to hear from you. And if you are an engineer working at a company that is marketing to developers, or hiring developers, if you tell your marketing department or your recruiting department about softwareengineeringdaily.com/sponsor, that is one way to help us out.

", + "Episodes Title": "Open Source Product Strategy with Shaun Connolly", + "Episodes Uid": "SED7404080055", + "Episodes Audio File": "c83e0473e1a7b221b4516615d3471e7d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "3h4", + "Episodes ID": "f455ea6e-e328-11ea-91a2-9fd2485b167b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2018_02_14_ProductionMLSystems.mp3", + "Episodes Pubdate Date": "2018-02-14", + "Episodes Summary": "

Pinterest is a visual feed of ideas, products, clothing, and recipes. Millions of users browse Pinterest to find images and text that are tailored to their interests.

Like most companies, Pinterest started with a large monolithic application that served all requests. As Pinterest’s engineering resources expanded, some of the architecture was broken up into microservices and Dockerized, which make the system easier to reason about.

To serve users with better feeds, Pinterest built a machine learning pipeline using Kafka, Spark, and Presto. User events are generated from the frontend, logged onto Kafka, and aggregated to build machine learning models. These models are deployed into Docker containers much like the production microservices.

Kinnary Jangla is a senior software engineer at Pinterest, and she joins the show to talk about her experiences at the company–breaking up the monolith, architecting a machine learning pipeline, and deploying those models into production.

Transcript provided by We Edit Podcasts. Software Engineering Daily listeners can go to weeditpodcasts.com/sed to get 20% off the first two months of audio editing and transcription services. Thanks to We Edit Podcasts for partnering with SE Daily. Please click here to view this show’s transcript.

", + "Episodes Title": "Machine Learning Deployments with Kinnary Jangla", + "Episodes Uid": "SED2746459569", + "Episodes Audio File": "d3097376a23b07d7ce287dd081a3b25b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5w0", + "Episodes ID": "ed7d6afa-e328-11ea-91a2-8706c256d77b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_06_27_CitusData_FoundingtoAcquisition.mp3", + "Episodes Pubdate Date": "2019-06-28", + "Episodes Summary": "

A new database company needs to solve numerous problems in order to succeed.

There are already lots of existing database companies, so a new company needs to find a way to strongly differentiate itself. Databases are core infrastructure, so a new database company must earn trust with its customers. A database is a complicated distributed system, so a database company must have strong engineering to get its product to market.

Citus Data was founded in 2011. Around that time, companies were looking for solutions to both their online transactional workloads and their large-scale offline analytics workloads. Citus Data built its company around Postgres, a popular database that has been around since 1996. Products from Citus Data include a Postgres scalability extension as well as a cloud-hosted offering for spinning up Postgres instances.

Citus Data was acquired by Microsoft earlier this year. In today’s episode, Umur Cubukcu joins the show to talk about the story of the company from its early days to its eventual acquisition. Umur describes the landscape of data systems in 2011 when the company started, and explains how that evolved to the current ecosystem. Umur also talks about how to make an acquisition successful and gives some perspective on the future of data platforms.

", + "Episodes Title": "Citus Data: Founding to Acquisition with Umur Cubukcu", + "Episodes Uid": "SED2953469591", + "Episodes Audio File": "7715ce793e182405dc2dee9909f620f4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2gs", + "Episodes ID": "07acf918-e329-11ea-91a2-9fd5c966d35c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/DataNauts.mp3", + "Episodes Pubdate Date": "2017-02-13", + "Episodes Summary": "

Infrastructure is a term that can mean many different things: your physical computer, the data center of your Amazon EC2 cluster, the virtualization layer, the container layer–on and on. In today’s episode, podcasters Chris Wahl and Ethan Banks discuss the past, present, and future of infrastructure with me.

Ethan and Chris host Datanauts, a podcast about infrastructure. In each episode, Datanauts goes deep on a topic such as networking, serverless, or OpenStack. As someone who hosts a similar podcast, I find it entertaining and educational to hear their points of view on a regular basis. If you like Software Engineering Daily, you might like Datanauts. And if you like Datanauts, you will love this episode of Software Engineering Daily.

", + "Episodes Title": "Infrastructure with Datanauts’ Chris Wahl and Ethan Banks", + "Episodes Uid": "SED8072148277", + "Episodes Audio File": "632c866d5cb8c94324ca06b9a695f63e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "78m", + "Episodes ID": "e9419498-e328-11ea-91a2-4b2f08a191a4", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_19_Matterport.mp3", + "Episodes Pubdate Date": "2020-05-19", + "Episodes Summary": "

Matterport is a company that builds 3-D imaging for the inside of buildings, construction sites, and other locations that require a “digital twin.” Generating digital images of the insides of buildings has a broad spectrum of applications, and there are considerable engineering challenges in building such a system.

Matterport’s hardware stack involves a camera built in-house by the company. The camera can take 360 degree scans of a room, stitch the imagery together, and make the digital twin available on the cloud.

Japjit Tulsi works at Matterport, and he joins the show to discuss 3-D imaging, and his role as CTO of the company.

", + "Episodes Title": "Matterport 3-D Imaging with Japjit Tulsi", + "Episodes Uid": "SED2323731249", + "Episodes Audio File": "48844dad20e23c368646332e0cc1205c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "28n", + "Episodes ID": "128acbb2-e329-11ea-91a2-f38d8be6ad62", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/cloudbuilding_edited.mp3", + "Episodes Pubdate Date": "2016-10-20", + "Episodes Summary": "

Google Compute Engine is the public cloud built by Google. It provides infrastructure- and platform-as-a-service capabilities that rival Amazon Web Services. Today’s guest Joe Beda was there from the beginning of GCE, and he was also one of the early engineers on the Kubernetes project.

Google’s internal systems have made it easy for employees to spin up compute resources, but it was not a simple task to make this internal cloud consumable by the public–not to mention competitive with AWS.  In order for a cloud provider to be successful, it needs to offer self-healing, self-managing infrastructure that can run microservices.

", + "Episodes Title": "Google Cloudbuilding with Joe Beda", + "Episodes Uid": "SED4853528923", + "Episodes Audio File": "ec06983d0efbabe1271115a41511b726.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4yr", + "Episodes ID": "f06dba8a-e328-11ea-91a2-07ad6095d923", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Zeromq_Edited.mp3", + "Episodes Pubdate Date": "2018-11-23", + "Episodes Summary": "

Originally posted on June 23, 2016.

Pieter Hintjens grew up writing software by himself. The act of writing code brought him great pleasure, but the isolated creative process disconnected him from the rest of the world. As his life progressed he became involved in open source communities, and he discovered a passion for human interaction.
\nOpen source software succeeds or fails on the strength of the community. One story of success is ZeroMQ, a popular open source distributed messaging system that was started by Pieter Hintjens. In this episode, Pieter gives his thoughts on human nature, distributed systems, and death. “A Protocol For Dying” is a blog post Pieter wrote recently, where he discussed his terminal diagnosis of cancer, and how it has reframed his perspective on life.

", + "Episodes Title": "Death and Distributed Systems with Pieter Hintjens Holiday Repeat", + "Episodes Uid": "SED8321257544", + "Episodes Audio File": "9d823abb9b66e25e22a17ce6e8ac4190.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "zr", + "Episodes ID": "2b4fa0fa-e329-11ea-91a2-0fdef011d8cc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Popcorn_Edited.mp3", + "Episodes Pubdate Date": "2015-11-23", + "Episodes Summary": "

Popcorn Time was a free, open-source application that allowed for streaming of movie and television show torrents.

Niv Sardi is an activist and developer based in Argentina, who previously worked on the main fork of Popcorn Time, popcorntime.io. Niv is also the founder of the Butter Project, a spin out project from Popcorn Time.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Popcorn Time with Niv Sardi", + "Episodes Uid": "SED7952465204", + "Episodes Audio File": "d711c1adbda3f305cfb332f2b0bfb092.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6bu", + "Episodes ID": "ebe4a17c-e328-11ea-91a2-ef4e916edc81", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_23_LinkedinHadoop.mp3", + "Episodes Pubdate Date": "2019-10-23", + "Episodes Summary": "

LinkedIn is a social network with petabytes of data. 

In order to store that data, LinkedIn distributes and replicates that data across a large cluster of machines running the Hadoop Distributed File System. In order to run calculations across its large data set, LinkedIn needs to split the computation up using MapReduce-style jobs.

LinkedIn has been developing its data infrastructure since the early days of the Hadoop ecosystem. LinkedIn started using Hadoop in 2008, and in the last 11 years, the company has adopted streaming frameworks, distributed databases, and newer execution runtimes like Apache Spark.

With the popularization of machine learning, there are more applications for data engineering than ever before. But the tooling around data engineering means that it is still hard for developers to find data sets, clean their data, and build reliable models. 

Carl Steinbach is an engineer at LinkedIn working on tools for data engineering. In today’s episode, Carl discusses the data platform inside LinkedIn, and the strategies that the company has developed around storing and computing large amounts of data. 

Full disclosure: LinkedIn is a sponsor of Software Engineering Daily.

", + "Episodes Title": "LinkedIn Data Platform with Carl Steinbach", + "Episodes Uid": "SED5216326754", + "Episodes Audio File": "b8a2dcf752bd4835f73b2f743da6e1be.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 206, + "Episodes ID": "1b9179a4-e329-11ea-91a2-2bf337c52e29", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Truecaller_Edited.mp3", + "Episodes Pubdate Date": "2016-06-08", + "Episodes Summary": "

The war against spam has been going on for decades. Email spam blockers and ad blockers help protect us from unwanted messages in our communication and browsing experience. These spam prevention tools are powered by machine learning, which catches most of the emails and ads that we don’t want to see. TrueCaller is a company that is bringing this quality of spam detection to our phone call systems.

Umut Alp is the CTO of TrueCaller, and he joins the show today to break down the engineering problems of preventing telephone call spam. Users of TrueCaller install it on their phone, and the software allows users to report when they have received a spam call. Using this reporting mechanism, and other learning algorithms, TrueCaller is able to learn what types of calls it should block from being accepted by your phone. Today on Software Engineering Daily, we discuss cell phone spam prevention.

", + "Episodes Title": "Phone Spam with Truecaller CTO Umut Alp", + "Episodes Uid": "SED9236085963", + "Episodes Audio File": "f6994246caff1541f42a304aad7dd807.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "625c7f78-fe04-11ea-aba9-8b7dd4d43023", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-24", + "Episodes Summary": "


", + "Episodes Title": "Salesforce Ecosystem with Kevin Poorman", + "Episodes Uid": "SED9230068465", + "Episodes Audio File": "6c5e8736b70dc53049af3e090294b04a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "zz", + "Episodes ID": "2afb4fbe-e329-11ea-91a2-3700c63f1e17", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Letsencrypt_Edited.mp3", + "Episodes Pubdate Date": "2015-11-30", + "Episodes Summary": "

Let’s Encrypt is a free, automated, and open certificate authority developed by the Internet Security Research Group (ISRG). The ISRG is a non-profit whose mission is to reduce financial, technological, and education barriers to secure communication over the Internet.

Josh Aas is the Co-founder and Executive Director of the ISRG. He is also a Senior Technology Strategist at Mozilla.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Let’s Encrypt with Josh Aas", + "Episodes Uid": "SED8877502865", + "Episodes Audio File": "a1388299b2a0ff56f879c02e4efcb3c1.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 219, + "Episodes ID": "1a7294f4-e329-11ea-91a2-171e28045df9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Zeromq_Edited.mp3", + "Episodes Pubdate Date": "2016-06-24", + "Episodes Summary": "

Pieter Hintjens grew up writing software by himself. The act of writing code brought him great pleasure, but the isolated creative process disconnected him from the rest of the world. As his life progressed he became involved in open source communities, and he discovered a passion for human interaction.
\nOpen source software succeeds or fails on the strength of the community. One story of success is ZeroMQ, a popular open source distributed messaging system that was started by Pieter Hintjens. In this episode, Pieter gives his thoughts on human nature, distributed systems, and death. “A Protocol For Dying” is a blog post Pieter wrote recently, where he discussed his terminal diagnosis of cancer, and how it has reframed his perspective on life.

", + "Episodes Title": "Death and Distributed Systems with Pieter Hintjens", + "Episodes Uid": "SED2519122041", + "Episodes Audio File": "9d823abb9b66e25e22a17ce6e8ac4190.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ww", + "Episodes ID": "ea40ad2a-e328-11ea-91a2-33bb220744e6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_06_ReactBestPracticesKentDodds.mp3", + "Episodes Pubdate Date": "2020-03-06", + "Episodes Summary": "

ReactJS developers have lots of options for building their applications, and those options are not easy to work through. State management, concurrency, networking, and testing all have elements of complexity and a wide range of available tools. Take a look at any specific area of JavaScript application development, and you can find highly varied opinions.

Kent Dodds is a JavaScript teacher who focuses on React, JavaScript, and testing. In today’s episode, Kent provides best practices for building JavaScript applications, specifically React. He provides a great deal of advice on testing, which is unsurprising considering he owns TestingJavaScript.com. Kent is an excellent speaker who has taught thousands of people about JavaScript, so it was a pleasure to have him on the show.

Kent is also speaking at Reactathon, a San Francisco JavaScript conference taking place March 30th and 31st in San Francisco. This week we will be interviewing speakers from Reactathon, and if you are interested in JavaScript and the React ecosystem then stay tuned, and if you hear something you like, you can check out the Reactathon conference in person.

", + "Episodes Title": "React Best Practices with Kent Dodds", + "Episodes Uid": "SED2447978489", + "Episodes Audio File": "96214b6c0344258720b78631aad1d634.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "10t", + "Episodes ID": "2a5934ea-e329-11ea-91a2-1f0457d76f60", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/React_Edited.mp3", + "Episodes Pubdate Date": "2015-12-03", + "Episodes Summary": "

React Native is leading to a future where a developer can build native experiences on web, iOS and Android platforms without having to write 3x the code.

Christopher Chedeau is an engineer at Facebook who works on the React team.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "The Future of React with Christopher Chedeau", + "Episodes Uid": "SED1032108307", + "Episodes Audio File": "db9ef4f6d13a9256d95dbd89f488cbed.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "a2ef94ce-f870-11ea-b172-4b58d6ddfad6", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-17", + "Episodes Summary": "


", + "Episodes Title": "Elementary Robotics with Arye Barnehama", + "Episodes Uid": "SED3752891542", + "Episodes Audio File": "11c76ee58fb1b437e5287330b68cfa4b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7d7", + "Episodes ID": "e8ac00c2-e328-11ea-91a2-53ca2467a8ea", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_02_DynamoDB.mp3", + "Episodes Pubdate Date": "2020-07-02", + "Episodes Summary": "

DynamoDB is a managed NoSQL database service from AWS. It is widely used as a transactional database to fulfill key-value and wide-column data models. In a previous show with Rick Houlihan, we explored how to build a data model and optimize the query patterns for a NoSQL database. 

Today’s show is about DynamoDB specifically: partitioning, indexing, query semantics, normalization, table design, and other subjects. We talk through how to be cost conscious, and how to integrate with event-based AWS Lambda triggers.

Alex DeBrie is the author of The DynamoDB Book, a book whose title speaks for itself. Alex has comprehensive experience with DynamoDB, and he joins the show to share that experience through a detailed discussion of use cases and strategies related to DynamoDB.

", + "Episodes Title": "DynamoDB with Alex DeBrie", + "Episodes Uid": "SED7303183438", + "Episodes Audio File": "13a5c0a0011e404c02ecd0b2f8b3925c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6yg", + "Episodes ID": "ea1b71e0-e328-11ea-91a2-637919e613d3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_18_InfraInvestingVivek.mp3", + "Episodes Pubdate Date": "2020-03-18", + "Episodes Summary": "

Software investing requires a deep understanding of the market, and an ability to predict what changes might occur in the near future. At the level of core infrastructure, software investing is particularly difficult. Databases, virtualization, and large scale data processing tools are all complicated, highly competitive areas.

As the software world has matured, it has become apparent just how big these infrastructure companies can become. Consequently, the opportunities to invest in these infrastructure companies have become highly competitive.

When a venture capital fund invests into an infrastructure company, the fund will then help the infrastructure company bring their product to market. This involves figuring out the product design, the sales strategy, and the hiring roadmap. A strong investor will be able to give insight into all of these different facets of building a software company.

Vivek Saraswat is a venture investor with Mayfield, a venture fund that focuses on early to growth-stage investments. Vivek joins the show to discuss his experience at AWS, Docker, and Mayfield, as well as his broad lessons around how to build infrastructure companies today.

", + "Episodes Title": "Infrastructure Investing with Vivek Saraswat", + "Episodes Uid": "SED8967330301", + "Episodes Audio File": "5b1a07960fb01a89d56e37760455f480.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2cf", + "Episodes ID": "0ee9c6c0-e329-11ea-91a2-cfd9658decef", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/netflixcaching_edited.mp3", + "Episodes Pubdate Date": "2016-12-09", + "Episodes Summary": "

Caching is a fundamental concept of computer science. When data is accessed frequently, we put that data in a place where it can be accessed more quickly–we put the data in a cache. When data is accessed less often, we leave it in a place where the access time is slow or expensive.

Netflix has a huge variety of data, and a huge variety of access patterns for how that data gets retrieved from storage. In today’s episode, Scott Mansfield gives an overview of Netflix’s caching architecture, including EVCache, the ephemeral, volatile cache built for Netflix’s cloud architecture.

As with other episodes about Netflix architecture, this show is a deeply technical case study.

", + "Episodes Title": "Netflix Caching with Scott Mansfield", + "Episodes Uid": "SED8219646423", + "Episodes Audio File": "c08af6ab89ae025434c5b1290a3da690.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2c1", + "Episodes ID": "0f3fbb34-e329-11ea-91a2-077b81c4f2fb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/algorithms_edited.mp3", + "Episodes Pubdate Date": "2016-12-05", + "Episodes Summary": "

When you are deciding who to marry, you are using an algorithm. The same is true when you are looking for a parking space, playing a game of poker, or deciding whether or not to organize your closet. Algorithms To Live By is a book about the computer science of human decisions. It offers strategies for how to think through everyday life like a computer scientist.

Brian Christian has a background in computer science and philosophy, and is an author of Algorithms to Live By. He joins the show to explain how the same algorithms and data structures we use for our computer programs can be applied to the real world.

", + "Episodes Title": "Algorithms to Live By with Brian Christian", + "Episodes Uid": "SED6949245471", + "Episodes Audio File": "7bc415b0ce6a3d545cbce3fc1164e8f8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1o2", + "Episodes ID": "2229044e-e329-11ea-91a2-eb3fcfbd8ef9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Monsanto_Edited_FInal.mp3", + "Episodes Pubdate Date": "2016-02-29", + "Episodes Summary": "

Monsanto is a company that is known for its chemical and biological engineering. It is less well known for its data science and software engineering teams. Tim Williamson is a data scientist at Monsanto, and on today’s show he talked about how he and a small group of engineers at Monsanto dramatically shifted the culture around data science-driven genetic engineering.

In this episode, Tim explains how useful graph databases are for modeling the genetic lineages, and talks about how Monsanto manages simulations and experiments on their genomics software pipeline. Tim also talks about how just a few engineers can create a cultural shift within a large company like Monsanto using the leverage allowed by software.

", + "Episodes Title": "Data Science at Monsanto with Tim Williamson", + "Episodes Uid": "SED2532516898", + "Episodes Audio File": "accc01d2f5f42dc56ae95b74d8d24262.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1n4", + "Episodes ID": "22a42d18-e329-11ea-91a2-8f417c4af841", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Browserwars_Edited.mp3", + "Episodes Pubdate Date": "2016-02-22", + "Episodes Summary": "

Internet Explorer, Google Chrome, Firefox–it’s easy to forget that these modern browsers descended from the war between Microsoft and Netscape. Today, we hear from a software engineer who was on the front lines of that war, back in 1992.

Eric Sink was one of the original developers of Spyglass, a browser that was licensed to both Microsoft AND Netscape. If you want to understand why that happened, and what the inside story of the browser wars is, and what the business of selling browser licenses was like in 1992, check out this episode of Software Engineering Daily.

", + "Episodes Title": "Browser Wars with Eric Sink", + "Episodes Uid": "SED6296793553", + "Episodes Audio File": "b5631f528d13e8d9fe1a5961df234d26.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1d8", + "Episodes ID": "23b5ee44-e329-11ea-91a2-c3e9e10f4bff", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Fluent_Edited_2.mp3", + "Episodes Pubdate Date": "2016-02-08", + "Episodes Summary": "

This week of shows on Software Engineering Daily focuses on O’Reilly’s Fluent Conference, a yearly software conference that focuses on the web and the tools used to build modern applications.

Software Engineering Daily is giving away a ticket to The Fluent Conference, which will be held March 8-10 in San Francisco. To be entered in a random drawing for this free ticket, tweet about your favorite episode of Software Engineering Daily between now and February 22nd. Include the hashtag #fluentconf and and tag us @software_daily to make sure we can see your tweet.

In today’s show, Jeff chats with Peter Cooper and Simon St Laurent, the organizers of Fluent. They discuss how the web is transitioning beyond the desktop and how to keep up with ever evolving javascript frameworks. This was also unique chance as well to learn why software conferences are so important.

", + "Episodes Title": "The Fluent Conference with Peter Cooper and Simon St. Laurent", + "Episodes Uid": "SED3348919921", + "Episodes Audio File": "c70c77cff631f44eee0c3d6a8dcbe72f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1op", + "Episodes ID": "21bd9308-e329-11ea-91a2-dfdcde9ee5e4", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Socket_Edited.mp3", + "Episodes Pubdate Date": "2016-03-04", + "Episodes Summary": "

Socket.io enables realtime bidirectional communication. But what does “realtime” actually mean? Today’s guest is Guillermo Rauch, the creator of Socket.IO, a widely used technology for client server communication. We discuss the nature of real-time apps like Uber and Google Docs, and talk about the API and usage of Socket.IO.

", + "Episodes Title": "Socket.IO and Realtime Applications with Guillermo Rauch", + "Episodes Uid": "SED4877077283", + "Episodes Audio File": "03ee980eba5764efe40de5d486c6a56c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "3c635752-fc7d-11ea-bce2-f3c639c10350", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-22", + "Episodes Summary": "


", + "Episodes Title": "Robinhood Engineering with Jaren Glover", + "Episodes Uid": "SED3892214477", + "Episodes Audio File": "18f5fd46dbc9bde0bd9d237fb80e4763.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6bk", + "Episodes ID": "ebf74732-e328-11ea-91a2-1fbc6ad39463", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_17_Gravitational.mp3", + "Episodes Pubdate Date": "2019-10-17", + "Episodes Summary": "

Modern applications are distributed systems. These applications require an installation mechanism that can run and update the software across multiple nodes. 

When a SaaS company starts to work with large enterprise customers, that company needs to figure out a way to deliver their product to the enterprise. This requires the SaaS company to deploy the product to whatever infrastructure the enterprise is running.

Some enterprises use on-prem infrastructure. Some use AWS. Some use a variety of cloud providers and on-premise servers. A SaaS company with limited resources must be able to have a standard deployment model that satisfies all of these different use cases.

Ev Kontsevoy is the CEO of Gravitational, a company that builds software for application delivery. Ev’s company maintains Gravity, an open source tool for application imaging and delivery. Ev was also the founder of Mailgun, a popular email API service. Mailgun was acquired by Rackspace, and in his time running Mailgun, Ev became deeply aware of the problems faced by developers and operators who manage server infrastructure.

Ev joins the show to discuss his experience building companies and the state of modern infrastructure. Full disclosure: Gravitational is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Gravity: Distributed Application Delivery with Ev Kontsevoy", + "Episodes Uid": "SED6558299776", + "Episodes Audio File": "184f0172407924b00aef6843c8794d63.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 229, + "Episodes ID": "1a176304-e329-11ea-91a2-4fbb1eca82ab", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Cloud_Providers_Edited.mp3", + "Episodes Pubdate Date": "2016-07-05", + "Episodes Summary": "

In 1999, it took $50,000 to buy a server. Once you bought that server, you had to know how to operate and maintain it. Today, cloud service providers have changed how we build software. Servers, load balancers, networking, storage–these hardware concerns have been turned into software.
\nDon Pezet joins the show today to discuss the fundamentals of a cloud service provider. These are the basics that you need to know about building and maintaining your application in the cloud. Don is a host of IT Pro TV, a company that makes training resources for engineers and operators. 

", + "Episodes Title": "Cloud Providers with Don Pezet", + "Episodes Uid": "SED7329084984", + "Episodes Audio File": "a424632fcd572d81b4fb1ccd9e1f2e90.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 745, + "Episodes ID": "e9a0de76-e328-11ea-91a2-77eab18ddb5a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_24_Rasa.mp3", + "Episodes Pubdate Date": "2020-04-24", + "Episodes Summary": "

Chatbots became widely popular around 2016 with the growth of chat platforms like Slack and voice interfaces such as Amazon Alexa. As chatbots came into use, so did the infrastructure that enabled chatbots. NLP APIs and complete chatbot frameworks came out to make it easier for people to build chatbots.

The first suite of chatbot frameworks were largely built around rule-based state machine systems. These systems work well for a narrow set of use cases, but fall over when it comes to chatbot models that are more complex. Rasa was started in 2015, amidst the chatbot fever. 

Since then, Rasa has developed a system that allows a chatbot developer to train their bot through a system called interactive learning. With interactive learning, I can deploy my bot, spend some time talking to it, and give that bot labeled feedback on its interactions with me. Rasa has open source tools for natural language understanding, dialogue management, and other components needed by a chatbot developer.

Tom Bocklisch works at Rasa, and he joins the show to give some background on the field of chatbots and how Rasa has evolved over time.

", + "Episodes Title": "Rasa: Conversational AI with Tom Bocklisch", + "Episodes Uid": "SED9930801567", + "Episodes Audio File": "35c3910c3cc53871e409f2da02443aba.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1r2", + "Episodes ID": "20556900-e329-11ea-91a2-67d6eba420f6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Siftery_Edited_2.mp3", + "Episodes Pubdate Date": "2016-03-18", + "Episodes Summary": "

Building a software business today requires lots of decision making. Building software isn’t just about choosing a programming language, or a framework, or a database. Developers have to choose the right cloud service provider, the best issue tracking service, the best hosted code repository, the clearest data visualization tools. We need a platform to compare the options between different products, all in one place.

In today’s episode, we talk to Ayan Barua from Siftery, a platform for software products and the companies who use them. Siftery’s mission is to help technologists find the best products for their job, whether they are a sysadmin or an advertising account manager. My discussion with Ayan covers the question of build versus buy, how to build a recommender system, and how software will be built in the future; this is also a great episode for anyone who is thinking of how to build a two-sided marketplace business.

", + "Episodes Title": "Building vs. Buying Software with Ayan Barua", + "Episodes Uid": "SED8139343860", + "Episodes Audio File": "370c75735d1eeaef1c63c3fde474cc6e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "21h", + "Episodes ID": "1a43d6dc-e329-11ea-91a2-b3abf7e5a3bc", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/ScyllaDB_Edited.mp3", + "Episodes Pubdate Date": "2016-06-29", + "Episodes Summary": "

Apache Cassandra is a distributed database that can handle large amounts of data with no single point of failure. Since 2008, Cassandra has been widely adopted and the software and the community around it have grown steadily. A software developer interacting with Cassandra uses CQL, the Cassandra Query Language. ScyllaDB is another open-source database that has been created to be totally compatible with CQL.
\nBy complying with CQL, the internals of ScyllaDB can be a vastly different rewrite from Cassandra. ScyllaDB uses C++, whereas Cassandra uses Java. ScyllaDB improves upon the performance characteristics of Cassandra, by optimizing for modern hardware, and Dor Laor joins the show today to discuss how ScyllaDB does all of this.

", + "Episodes Title": "Cassandra Compliant ScyllaDB with Dor Laor", + "Episodes Uid": "SED1672777571", + "Episodes Audio File": "a5ea36ee73c0c1e996be6902c00688c0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1tm", + "Episodes ID": "1f88f3f2-e329-11ea-91a2-2bd4ff316fb9", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/cloudinary_Edited.mp3", + "Episodes Pubdate Date": "2016-03-31", + "Episodes Summary": "

Ten years ago, building a highly scalable image delivery service would require millions of dollars in upfront costs, and hours of work configuring hardware server infrastructure. Today, it is possible to bootstrap this type of service, with minimal investment.

Today’s episode is about building a content delivery network for images and video. Today’s guest is Itai Lahan, CEO of Cloudinary. We discuss Cloudinary’s early product infrastructure, and how they have evolved as a company since then. We also talk in detail about the venture capital landscape of Silicon Valley today, and how to strategize about raising money. Full disclosure, Cloudinary is a sponsor of Software Engineering Daily.

", + "Episodes Title": "Bootstrapping a SaaS for Developers with Itai Lahan", + "Episodes Uid": "SED9501898274", + "Episodes Audio File": "b9483cbdab5fc66fb89fddc8df1d4b3f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 744, + "Episodes ID": "e9a5564a-e328-11ea-91a2-6bf26d3faed7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_23_CloudBurst.mp3", + "Episodes Pubdate Date": "2020-04-23", + "Episodes Summary": "

Serverless computing is a way of designing applications that do not directly address or deploy application code to servers. Serverless applications are composed of stateless functions-as-a-service and stateful data storage systems such as Redis or DynamoDB. 

Serverless applications allow for scaling up and down the entire architecture, because each component is naturally scalable. And this pattern can be used to create a wide variety of applications. The functions-as-a-service can handle the compute logic, and the data storage systems can handle the storage. But these applications do not give the developer as much flexibility as an ideal serverless system might. The developer would need to use cloud-specific state management systems.

Vikram Sreekanti is the creator of Cloudburst, a system for stateful functions as a service. Cloudburst is architected as a set of VMs that can execute functions-as-a-service that are scheduled onto them. Each VM can utilize a local cache, as well as an autoscaling key-value store called Anna which is accessible to the Cloudburst runtime components. Vikram joins the show to talk about serverless computing and his efforts to build stateful serverless functionality.

", + "Episodes Title": "Cloudburst: Stateful Functions-as-a-Service with Vikram Sreekanti", + "Episodes Uid": "SED1493784056", + "Episodes Audio File": "585ddbd4184275b64c1c178965dc7905.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 243, + "Episodes ID": "186f1c54-e329-11ea-91a2-df8f5509276d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/The_Art_of_Monitoring_Edited.mp3", + "Episodes Pubdate Date": "2016-07-28", + "Episodes Summary": "

Monitoring translates machine data into actionable business metrics, and is a key component of a modern software company. James Turnbull’s new book “The Art of Monitoring” describes how organizations can build their monitoring infrastructure.

James joins the show today to outline the strategies that a company can use to proactively monitor their systems. We talk about pull- vs. push-based monitoring, events, logging, metrics, and James’s experience as CTO of Kickstarter.

", + "Episodes Title": "The Art of Monitoring with James Turnbull", + "Episodes Uid": "SED1228573908", + "Episodes Audio File": "638ea367dcf9bfb15e10ed2b586a92a7.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "28x", + "Episodes ID": "1274fc60-e329-11ea-91a2-7b5fdb2809c7", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/uber_database_edited.mp3", + "Episodes Pubdate Date": "2016-10-24", + "Episodes Summary": "

When Uber’s engineering team published a blog post about moving to MySQL from Postgres, Markus Winand started receiving lots of email. Markus writes about databases on his blog “Use The Index, Luke,” a guide to database performance for developers. The people emailing Markus wanted to know–if Postgres doesn’t work well for Uber, is it safe to use for anyone?

Markus wrote a detailed blog post that was a response to Uber’s discussion of Postgres, and in today’s episode Markus explains why Postgres is perfectly fine for most applications.

Most developers are not experts in choosing between different databases. The average developer knows the difference between a NoSQL database like Mongo and a normalized SQL database like MySQL–but that developer might not know the more subtle differences between different SQL databases like MySQL and Postgres.

That is why Markus’s site is so useful, and why it was a pleasure to have him on the show.

", + "Episodes Title": "Database Choices and Uber with Markus Winand", + "Episodes Uid": "SED6860593171", + "Episodes Audio File": "5549cbc7b5b07eed8d1e4ac674514bc6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6a6", + "Episodes ID": "ec17c3ae-e328-11ea-91a2-7f01992708aa", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_08_Traces.mp3", + "Episodes Pubdate Date": "2019-10-08", + "Episodes Summary": "

Video surveillance impacts human lives every day. 

On most days, we do not feel the impact of video surveillance. But the effects of video surveillance have tremendous potential. It can be used to solve crimes and find missing children. It can be used to intimidate journalists and empower dictators. Like any piece of technology, video surveillance can be used for good or evil.

Video recognition lets us make better use of video feeds. A stream of raw video doesn’t provide much utility if we can’t easily model its contents. Without video recognition, we must have a human sitting in front of the video to manually understand what is going on in that video.

Veronica Yurchuk and Kosh Shysh are the founders of Traces.ai, a company building video recognition technology focused on safety, anonymity, and positive usage. They join the show to discuss the field of video analysis, and their vision for how video will shape our lives in the future.

", + "Episodes Title": "Traces: Video Recognition with Veronica Yurchuk and Kostyantyn Shysh", + "Episodes Uid": "SED1542798936", + "Episodes Audio File": "138e465b0a5503dbe33956f90f9d83f5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "13h", + "Episodes ID": "29652530-e329-11ea-91a2-9377b059f08a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Internet_of_Things_and_Devops_with_Anders_Wallgren.mp3", + "Episodes Pubdate Date": "2015-12-10", + "Episodes Summary": "

The Internet of Things era is upon us, and with it the related concerns of security, privacy and reliability of the connected systems. This episode explores these issues and how companies can prevent these problems through better development processes and lifecycle management.

Anders Wallgren is the CTO of Electric Cloud, which builds products to help companies optimize their software build, test, and deployment process.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Internet of Things and DevOps with Anders Wallgren", + "Episodes Uid": "SED4425767025", + "Episodes Audio File": "7789e6a62c45a7f665ed2c2fd720d43c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6hm", + "Episodes ID": "eb499b78-e328-11ea-91a2-fbb018d3de28", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_06_LinkerdMarketStrategy.mp3", + "Episodes Pubdate Date": "2019-12-06", + "Episodes Summary": "

The container orchestration wars ended in 2016 with Kubernetes being the most popular open source tool for deploying and managing infrastructure. Since that time, most large enterprises have been implementing a “platform strategy” based around Kubernetes.

A platform strategy is a plan for creating a consistent experience for software engineers working throughout an enterprise. At most companies, a software engineer should be thinking about business logic–whether that logic is related to banking, insurance, oil and gas, or e-commerce. 

Today, engineers at many enterprises need to think about continuous delivery, application deployment, security policy management, and other deeply technical problems that have nothing to do with the business that they are actually working at. Kubernetes is a foundational open source building block that allows enterprises to base the rest of their infrastructure decisions around. Kubernetes has made it much more viable for enterprises to pursue a platform strategy.

With widespread adoption of Kubernetes, there is a business opportunity for companies that can offer other platform solutions that build on top of Kubernetes. A service mesh is one such tool. A service mesh provides networking and security features for all the services in an organization.

The service mesh category is a large business opportunity because it sits on the critical path of every network request that goes through an enterprise. It is a potential insertion point for lots of other products including logging agents, distributed tracing, network packet scanning, security policy management, and A/B testing.

The potential for business expansion is why so many businesses are entering the service mesh category today, from cloud providers to API gateways. Buoyant was one of the first companies to work on a service mesh tool, with the Linkerd open source project. William Morgan is the CEO of Buoyant, and he returns to the show to discuss the competitive dynamics of the service mesh market.

", + "Episodes Title": "Linkerd Market Strategy with William Morgan", + "Episodes Uid": "SED8578430439", + "Episodes Audio File": "ea4b5258ece4d7313da89358cc1d4ca8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6we", + "Episodes ID": "ea55ec6c-e328-11ea-91a2-239a44b5e082", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_02_nextjsGuillermoRauch.mp3", + "Episodes Pubdate Date": "2020-03-02", + "Episodes Summary": "

When ReactJS became popular, frontend web development became easier. But React is just a view layer. Developers who came to React expecting a full web development framework like Ruby on Rails or Django were required to put together a set of tools to satisfy that purpose.

A full-stack JavaScript framework has numerous requirements. How does it scale? How does it handle server-side rendering versus client-side rendering? Should GraphQL be included by default? How should package management work?

Guillermo Rauch is the creator of NextJS, a popular framework for building React applications. He is also the CEO of ZEIT, a cloud hosting company. Guillermo joins the show to discuss NextJS, and his vision for how the React ecosystem will evolve in the near future, as features such as React Suspense and Concurrent Mode impact the developer experience.

Guillermo is also speaking at Reactathon, a San Francisco JavaScript conference taking place March 30th and 31st in San Francisco. This week we will be interviewing speakers from Reactathon, and if you are interested in JavaScript and the React ecosystem then stay tuned, and if you hear something you like, you can check out the Reactathon conference in person.

", + "Episodes Title": "NextJS with Guillermo Rauch", + "Episodes Uid": "SED4360751577", + "Episodes Audio File": "7e47ecff2e36acdddcaec3bc31b1f5c6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1uj", + "Episodes ID": "1f359df6-e329-11ea-91a2-0b05848a79e2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Hashi_Edited_2.mp3", + "Episodes Pubdate Date": "2016-04-06", + "Episodes Summary": "

Application delivery has become more complex as software architectures have moved into the cloud. Data center infrastructure has turned into code to be manipulated, and software engineering teams are adjusting their strategies.

HashiCorp is a company that builds open-source software for application development and deployment. Mitchell Hashimoto is the founder of HashiCorp, and he joins us to discuss a modern approach to application delivery, and the tools HashiCorp is developing.

", + "Episodes Title": "Automating Infrastructure at HashiCorp with Mitchell Hashimoto", + "Episodes Uid": "SED2235284065", + "Episodes Audio File": "23c17bd52f59cc633a1246414ef9e2f3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 208, + "Episodes ID": "1b716f74-e329-11ea-91a2-3b1cd8dbfebb", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Serverless_Edited.mp3", + "Episodes Pubdate Date": "2016-06-10", + "Episodes Summary": "

Virtual machines were the unit of cloud computation for many years. Amazon Web Services pioneered the democratized model of allowing anyone to deploy a service to the cloud, running on a virtual machine on Amazon’s servers. After virtual machines, containers have become the unit of scale in the cloud. We break up our virtualized servers into even smaller units of computation called containers. Today, the unit of compute is getting reduced even more, with the introduction of serverless architecture.

Serverless architectures started getting talked about after Amazon Web Services released a service called AWS Lambda, which allows users to have pieces of code run in response to events. Programmers write a function and hand it off to Amazon, and Amazon will run that function call, and only charge the programmer when the function is actually called. This is in contrast to the cost model of containers or virtual machines, which users pay for even while they are running idle.

Today’s guest Austen Collins believes that serverless computing is the model of the future, and he created a company called Serverless around this idea. His company Serverless provides an application framework for building applications exclusively on Amazon Web Services Lambda.

", + "Episodes Title": "Serverless Framework with Austen Collins", + "Episodes Uid": "SED1180115096", + "Episodes Audio File": "ee7b51ad3a133ad2912918312f743d11.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 237, + "Episodes ID": "19c2ba66-e329-11ea-91a2-6b435620725d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Cassandra_jon_haddad_Edited.mp3", + "Episodes Pubdate Date": "2016-07-13", + "Episodes Summary": "

Data modeling is the process of creating relationships and rules about objects, so that we can decide how to store them in a database. Data modeling defines how we store and query our database systems.

Today’s episode features a discussion of data modeling in Cassandra with Jon Haddad, an evangelist at Datastax. The distributed nature of Cassandra creates some unique rules around how we should model our Cassandra tables. If you are new to Cassandra, there are a few episodes in the past that you may want to listen to first.
\nSpecial thanks to Caleb Meredith and Ben Johnson from the SE Daily community who helped the preparation of this episode

", + "Episodes Title": "Cassandra Data Modeling with Jon Haddad", + "Episodes Uid": "SED3401650840", + "Episodes Audio File": "9221f7fb176302a95b39fb452c1f76d0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "", + "Episodes ID": "13215cae-ebe3-11ea-aeab-efc44f70aef8", + "Episodes Original URL": "", + "Episodes Pubdate Date": "2020-09-01", + "Episodes Summary": "


", + "Episodes Title": "WebAssembly Migration with Nicolo Davis", + "Episodes Uid": "SED7926052946", + "Episodes Audio File": "b0d73dca43e05c259b9f11a568b486a0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6xf", + "Episodes ID": "ea36bf22-e328-11ea-91a2-7f54fb139b28", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_10_OneGraph.mp3", + "Episodes Pubdate Date": "2020-03-10", + "Episodes Summary": "

GraphQL is a system that allows frontend engineers to make requests across multiple data sources using a simple query format. In GraphQL, a frontend developer does not have to worry about the request logic for individual backend services. The frontend developer only needs to know how to issue GraphQL requests from the client, and these requests are handled by a GraphQL server.

GraphQL is mostly used to issue queries across internal databases and services. But many of the data sources that a company needs to query in modern infrastructure are not databases–they are APIs like Salesforce, Zendesk, and Stripe. These API companies might store a large percentage of the data that a given company needs to query, and executing queries, subscriptions, and joins against these APIs is not a simple task.

OneGraph is a company that builds integrations with third-party services and exposes them through a GraphQL interface. Sean Grove is a founder of OneGraph, and he joins the show to explain the problem that OneGraph solves, how OneGraph is built, and some of the difficult engineering challenges required to design OneGraph. 

", + "Episodes Title": "OneGraph: GraphQL Tooling with Sean Grove", + "Episodes Uid": "SED4622220128", + "Episodes Audio File": "efc51da512c346f1528e4dbb8ba76ee3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1lj", + "Episodes ID": "22874900-e329-11ea-91a2-bb77fb3cac46", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Voltdb_Edited.mp3", + "Episodes Pubdate Date": "2016-02-24", + "Episodes Summary": "

NewSQL is a class of modern relational databases that seek to provide the same scalable performance of NoSQL systems for OLTP, while still maintaining the ACID guarantees of a traditional database system. VoltDB is a NewSQL database, designed in part by Turing Award Winner Michael Stonebraker.

Today’s guest is John Hugg, a founding engineer at VoltDB. Today’s show covers the internals of VoltDB, including concepts like tunable consistency, database replication, and the advantages of a deterministic logical log.

", + "Episodes Title": "VoltDB and In-Memory Databases with John Hugg", + "Episodes Uid": "SED6596663099", + "Episodes Audio File": "03dc2ef30dafd5df23bdd576e0af9587.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "79f", + "Episodes ID": "e921adfe-e328-11ea-91a2-fbd2904dd2e5", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_28_DistSystemsResearch.mp3", + "Episodes Pubdate Date": "2020-05-28", + "Episodes Summary": "

Every software company is a distributed system, and distributed systems fail in unexpected ways. 

This ever-present tendency for systems to fail has led to the rise of failure testing, otherwise known as chaos engineering. Chaos engineering involves the deliberate failure of subsystems within an overall system to ensure that the system itself can be resilient to these kinds of unexpected failures.

Peter Alvaro is a distributed systems researcher who has published papers on a range of subjects, including debugging, failure testing, databases, and programming languages. He works with both academia and industry. Peter joins the show to discuss his research topics and goals.

", + "Episodes Title": "Distributed Systems Research with Peter Alvaro", + "Episodes Uid": "SED6008847348", + "Episodes Audio File": "67d61f839c886b40c7d4423cc6f2f055.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 701, + "Episodes ID": "e9fb386c-e328-11ea-91a2-d3a73c80e58b", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_03_27_CloudKitchenSoftware.mp3", + "Episodes Pubdate Date": "2020-03-27", + "Episodes Summary": "

Food delivery apps have changed how the restaurant world operates. After seven years of mobile food delivery, the volume of food ordered through these apps has become so large that entire restaurants can be sustained solely through the order flow that comes in from the apps. This raises the question as to why you even need an “on-prem” restaurant.

A cloud kitchen is a large, shared kitchen where food is prepared for virtual restaurants. These virtual restaurants exist only on mobile apps. There are no waiters, there are only the food delivery couriers who pick up the food from these warehouse-sized food preparation facilities. 

A virtual restaurant entrepreneur could open up multiple restaurants operated from the same cloud kitchen. The mobile app user might see separate restaurant listings for a pizza place, a cookie bakery, and a Thai food restaurant, when all of them are operated by the same restaurateur.

Ashley Colpaart is the founder of The Food Corridor, a system for cloud kitchen management. Ashley joins the show to talk about the dynamics of virtual restaurants and the cloud kitchen industry.

", + "Episodes Title": "Cloud Kitchen Platform with Ashley Colpaart", + "Episodes Uid": "SED7960209773", + "Episodes Audio File": "13f63498cb608086d9aa36a4b8cbbaff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2dm", + "Episodes ID": "0ceaa588-e329-11ea-91a2-d3396f4b6054", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/transcriptic_edited.mp3", + "Episodes Pubdate Date": "2016-12-28", + "Episodes Summary": "

A biologist wants to study the genetic makeup of an organism. A pharmaceutical researcher wants to test the effects of an experimental drug. These types of experiments require a deep knowledge of the scientific domain as well as the lab techniques to produce the data that will eventually yield a result.

Transcriptic is a robotic biology laboratory that allows you to make requests for experiments to run remotely. Scientists who use Transcriptic do not have to perform wet lab experimentation. The robotic laboratory process has the potential to do for biology what Amazon Web Services did for computing.

Max Hodak is a cofounder of Transcriptic and joins me today to explain how a robotic laboratory works. There are a wide variety of challenges, from hardware integration to software reverse engineering–but we also talk about why it is worth it to overcome these challenges, including a discussion of the “reproducibility crisis” that is undermining faith in our scientific experiments.

", + "Episodes Title": "Robot Cloud Lab with Max Hodak", + "Episodes Uid": "SED5688878620", + "Episodes Audio File": "8f39fc1f0944412eaf5b90a7ce76029b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6kp", + "Episodes ID": "eb0f8dd4-e328-11ea-91a2-131bfdd36813", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_07_ContainersAbbyFuller.mp3", + "Episodes Pubdate Date": "2020-01-07", + "Episodes Summary": "

Amazon’s container offerings include ECS (Elastic Container Service), EKS (Elastic Kubernetes Service), and Fargate. Through these different offerings, Amazon provides a variety of ways that a user can manage Kubernetes clusters and standalone container instances. The choice of which containerization system to choose depends on the needs of the user, and the tradeoffs they want to make on control and portability.

Amazon’s container products have been designed in the context of a shifting competitive landscape. Kubernetes presents a potential long-term threat to Amazon’s status as the most popular cloud provider. Properly responding to this threat has required Amazon to extend itself into the world of open source, contributing to Kubernetes and having more conversations with customers who want their products to have the high quality user experience of AWS along with the open characteristics of Kubernetes.

Abby Fuller is a principal technologist with Amazon who works on containers and Linux. Abby joins the show to describe Amazon’s perspective on containers and Kubernetes.

", + "Episodes Title": "Amazon Kubernetes with Abby Fuller", + "Episodes Uid": "SED9965731641", + "Episodes Audio File": "f623e73e2e8dd71f43f68e1f7c825ef8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6tp", + "Episodes ID": "ea7ac69a-e328-11ea-91a2-ef44fe294748", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_02_19_MaterializeSQL.mp3", + "Episodes Pubdate Date": "2020-02-19", + "Episodes Summary": "

Distributed stream processing frameworks are used to rapidly ingest and aggregate large volumes of incoming data. These frameworks often require the application developer to write imperative logic describing how that data should be processed. 

For example, a high volume of clickstream data that is getting buffered to Kafka needs to have a stream processing system evaluate that data to prepare it for a data warehouse, Spark, or some other queryable environment. In practice, many developers simply want to have the high volume of data become queryable in the fewest number of steps possible.

Materialize is a streaming SQL materialized view engine that provides materialized views over streaming data. The materialized views are incrementally updated over time and reconciled with new data that may have come in out of order.

Arjun Narayan and Frank McSherry are the co-founders of Materialize, a company whose technology is based on the Naiad paper, which was written at Microsoft Research. Arjun and Frank join the show to talk about modern streaming systems and their strategy for taking an academic paper and productizing it.

", + "Episodes Title": "Materialize: Streaming SQL on Timely Data with Arjun Narayan and Frank McSherry", + "Episodes Uid": "SED3415287763", + "Episodes Audio File": "a56c28ba4a2176e589a2b6d994b3002f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1z4", + "Episodes ID": "1c915be4-e329-11ea-91a2-93b0031846e6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/microservices_Edited.mp3", + "Episodes Pubdate Date": "2016-05-20", + "Episodes Summary": "

Google has built a microservices architecture on top of the internal container management system called Borg. These services communicate over an internal protocol known as Stubby. Borg and Stubby are tightly coupled to Google’s infrastructure–it would not make sense for Google to open source them–but Google has worked with the open source community to develop open source projects with the core functionality of Borg and Stubby. These projects are known as Kubernetes and gRPC.


\nSandeep Dinesh works on the Google Cloud Platform team as a developer advocate. Our conversation explores how a client application request from an app like Gmail would communicate with Google’s servers, where the request is handled by a network of microservices. We also talk about where Google Cloud Platform is evolving, and how it offers a competitive, differentiated model from Amazon Web Services.

", + "Episodes Title": "Google’s Microservices: Kubernetes and gRPC with Sandeep Dinesh", + "Episodes Uid": "SED8729629257", + "Episodes Audio File": "1400f99f35e0c44f75f6b4bf9f59c0db.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 753, + "Episodes ID": "e99ae084-e328-11ea-91a2-f35d38f0360e", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_27_Dask.mp3", + "Episodes Pubdate Date": "2020-04-27", + "Episodes Summary": "

Python is the most widely used language for data science, and there are several libraries that are commonly used by Python data scientists including Numpy, Pandas, and scikit-learn. These libraries improve the user experience of a Python data scientist by giving them access to high level APIs.

Data science is often performed over huge datasets, and the data structures that are instantiated with those datasets need to be spread across multiple machines. To manage large distributed datasets, a library such as scikit-learn can use a system called Dask. Dask allows the instantiation of data structures such as a Dask dataframe or a Dask array.

Matthew Rocklin is the creator of Dask. He joins the show to talk about distributed computing with Dask, its use cases, and the Python ecosystem. He also provides a detailed comparison between Dask and Spark, which is also used for distributed data science.

", + "Episodes Title": "Dask: Scalable Python with Matthew Rocklin", + "Episodes Uid": "SED1730097592", + "Episodes Audio File": "c64706a8ffe7958bba9be169cd7cd12c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2a1", + "Episodes ID": "113f75b4-e329-11ea-91a2-3fc616ca2222", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/botday_edited.mp3", + "Episodes Pubdate Date": "2016-11-12", + "Episodes Summary": "

Bot Day was an O’Reilly conference featuring talks from some of the leading figures in the bot industry. Before I attended Bot Day, I knew there were lots of applications for chatbots, but I didn’t realize how good the tooling has gotten–it’s very easy to get started with chatbots today so if you are a developer and you have a basic idea, I suggest checking out the videos from Bot Day, as they are a great resource for how to get started.

When I was at the conference, I had a number of conversations with Edaena Salinas, who hosts The Women In Tech Show. We also caught up a few weeks after the conference to discuss our reflections on Bot Day.

", + "Episodes Title": "Bot Day", + "Episodes Uid": "SED3585002130", + "Episodes Audio File": "e80269d64e3f139f6ef432a55c673508.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "78o", + "Episodes ID": "e938ed98-e328-11ea-91a2-c348cb8ec2cf", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_05_21_ArcGIS.mp3", + "Episodes Pubdate Date": "2020-05-21", + "Episodes Summary": "

Geospatial analytics tools are used to render visualizations for a vast array of applications. Data sources such as satellites and cellular data can gather location data, and that data can be superimposed over a map. A map-based visualization can allow the end user to make decisions based on what they see.

ArcGIS is one of the most widely used geospatial analytics platforms. It is created by ESRI, the Environmental Systems Research Institute, which was started in 1969. Today, ESRI products have 40% of the global market share of geospatial analytics software.

Max Payson is a solutions engineer at ESRI, and he joins the show to talk about applications of ArcGIS, and the landscape of GIS more broadly.

", + "Episodes Title": "ArcGIS: Geographic Information Software with Max Payson", + "Episodes Uid": "SED6994320152", + "Episodes Audio File": "957b46e0336e3665332fb98b25b71960.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7c5", + "Episodes ID": "e8e15f10-e328-11ea-91a2-d77969044874", + "Episodes Original URL": "https://sd-profile-pictures.s3-us-west-2.amazonaws.com/adfree/2019_11_21_JuliaEvansHTTP_adfree.mp3", + "Episodes Pubdate Date": "2020-06-17", + "Episodes Summary": "

Originally published November 21, 2019. We are taking a few weeks off. We’ll be back soon with new episodes.

HTTP is a protocol that allows browsers and web applications to communicate across the Internet.

Everyone knows that HTTP is doing some important work, because “HTTP” is at the beginning of most URLs that you enter into your browser. You might be familiar with the request/response model, and HTTP request methods such as GET, PUT, and POST. But unless you have had a reason to learn more about the details of HTTP, you probably don’t know much more than that.

Julia Evans is a software engineer and writer who creates Wizard Zines, a series of easy-to-read online magazines that explain technical software topics. Julia’s zines include “Linux Debugging Tools”, “Help! I Have A Manager!”, and recently “HTTP: Learn your browser’s language”.

Her zines are a creative, innovative format for describing the world of software engineering while also exploring her own artistic pursuits in writing, design, and illustration. Julia was previously on the show to discuss Ruby profiling, and she returns to the show to discuss HTTP, as well as her creative process and goals with Wizard Zines.

", + "Episodes Title": "HTTP with Julia Evans (Summer Break Repeat)", + "Episodes Uid": "SED4629187359", + "Episodes Audio File": "ae366a1057bbd7292824c9c291c6ae7e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4yk", + "Episodes ID": "f07ff8a8-e328-11ea-91a2-ab24513ee874", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Schedulers_Edited.mp3", + "Episodes Pubdate Date": "2018-11-19", + "Episodes Summary": "

Originally published on July 6, 2016.

Scheduling is the method by which work is assigned to resources to complete that work. At the operating system level, this can mean scheduling of threads and processes. At the data center level, this can mean scheduling Hadoop jobs or other workflows that require the orchestration of a network of computers.
\nAdrian Cockcroft worked on scheduling at Sun Microsystems, eBay, and Netflix. In each of these environments, the nature of what was being scheduled was different, but the goals of the scheduling algorithms were analogous–throughput, response time, and cache affinity are relevant in different ways at each layer of the stack.

Adrian is well-known for helping bring Netflix onto Amazon Web Services, and I recommend watching the numerous YouTube videos of Adrian talking about that transformation.

", + "Episodes Title": "Schedulers with Adrian Cockcroft Holiday Repeat", + "Episodes Uid": "SED3141163396", + "Episodes Audio File": "77b0f1d56e01f3a47eaaa029dd3ac421.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2d3", + "Episodes ID": "0e00689a-e329-11ea-91a2-03d9604d5448", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/reactivemicroservices_edited.mp3", + "Episodes Pubdate Date": "2016-12-19", + "Episodes Summary": "

For many years, software companies have been breaking up their applications into individual services for the purpose of isolation and maintainability. In the early 2000s, we called this pattern “service-oriented architecture”. Today we call it “microservices”. Why did we change that terminology? Did the services get smaller? Not exactly.

Jonas Boner suggests that the movement towards cloud and the increased prevalence of mobile changes how we look at these services–so much that we needed to change the terminology necessary to even talk about them. And once the conversation has shifted to “microservices”, what steps do we need to take to implement them properly?

The reactive manifesto is a collection of principles for how to build applications. When the reactive manifesto is applied to the idea of microservices, we get reactive microservices, which Jonas and I discuss in today’s episode.

", + "Episodes Title": "Reactive Microservices with Jonas Boner", + "Episodes Uid": "SED9155996104", + "Episodes Audio File": "eb566441e5fb0026a81421c332bfcd07.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6ho", + "Episodes ID": "eb403420-e328-11ea-91a2-cfcd694a1ee2", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_10_MoonlightWork2.mp3", + "Episodes Pubdate Date": "2019-12-10", + "Episodes Summary": "

Offices have historically been the place where most knowledge work takes place.

An office is a central meeting point for everyone in an organization. Offices allow for high bandwidth, in-person communication. Employees have access to shared resources, such as food, tables, and quiet working space. Offices provide a means of encouraging a common culture within a given workplace.

There are also significant downsides to offices–most notably the commute. Employees often spend between one and four hours per day driving to the office. Office work creates a huge restriction for parents with a young child to take care of. Many employees feel more productive when they are working at home, or working from a coffee shop.

Remote work is becoming an increasingly popular mode of work for knowledge workers. Remote work has been made possible by increased bandwidth, more powerful computers, and new communications software such as Slack and Zoom.

Remote work is a powerful trend that is reshaping how knowledge workers spend their time. It is also changing how companies are structured. A “remote first” culture impacts hiring, human resources, engineering, sales, work-life balance and every other aspect of operations. The downstream impacts of remote work will change the labor market even more thoroughly, and cause us to rethink contracting, equity structures, and the traditional five day workweek.

Philip Thomas is the co-founder and CEO of Moonlight Work, a marketplace for software engineers who work on contract projects full-time or part-time. Philip is also the co-author of the Remote Work Encyclopedia, which is a collection of strategies and tactics for knowledge workers and companies that are looking to adapt successfully to the changes that remote work is bringing to the world.

Philip joins the show to discuss remote work and his experience building Moonlight. Full disclosure: I am an investor in Moonlight Work.

", + "Episodes Title": "Remote Work with Philip Thomas", + "Episodes Uid": "SED9259536607", + "Episodes Audio File": "7fbfc7ebec383f83413196e040c66896.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6kx", + "Episodes ID": "eb0aa904-e328-11ea-91a2-5b7c413166ef", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_08_AmazonEC2.mp3", + "Episodes Pubdate Date": "2020-01-08", + "Episodes Summary": "

Amazon EC2 (Elastic Compute Cloud) is a virtualized server product that provides the user with scalable compute infrastructure. EC2 was created in 2006 as one of the first three AWS services along with S3 and Simple Queueing Service. Since then, EC2 has provided the core server infrastructure for many of the companies that have been built in the cloud. 

A large scale virtualization product requires its engineers to have a deep understanding of scheduling and multitenancy. In previous shows, we have touched on subjects such as hypervisors, the noisy neighbor problem, the cold start problem, and other aspects of multitenant infrastructure. To make EC2 successful, these issues must be continuously revisited and resolved at different areas of the stack.

Dave Brown joined the EC2 team in 2007, and now leads the EC2 Compute, Networking, and Load Balancing teams as a Vice President. Dave joins the show to discuss the history of EC2 and the canonical problems of virtualized server infrastructure.

", + "Episodes Title": "Amazon EC2 with Dave Brown", + "Episodes Uid": "SED2918076915", + "Episodes Audio File": "6fb2aca8257f8bab088e73f1e4330cff.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 210, + "Episodes ID": "1a78be2e-e329-11ea-91a2-a7b39891a854", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Bouyant_Edited.mp3", + "Episodes Pubdate Date": "2016-06-23", + "Episodes Summary": "

Six years ago, Twitter was experiencing outages due to high traffic. Back in 2010 Twitter was built as a monolithic Ruby on Rails application. Twitter migrated to a microservices architecture to fix these problems. During this migration, the engineers at Twitter learned how to build and scale highly distributed microservice architectures.

William Morgan was an engineer at Twitter during that time, and he is now the CEO of Buoyant.io, a company building open-source microservices infrastructure. Some of the big problems at Twitter were solved at the communication layer, using an RPC library called Finagle. At Buoyant, those lessons are being applied to a project called Linkerd, an RPC proxy.

", + "Episodes Title": "Scaling Twitter with Buoyant.io’s William Morgan", + "Episodes Uid": "SED6703465014", + "Episodes Audio File": "14b6a1d8d9e7d371326e6542cd83edfd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5xh", + "Episodes ID": "ed29f582-e328-11ea-91a2-af93020d0da5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_16_FacebookEngineeringCulture.mp3", + "Episodes Pubdate Date": "2019-07-16", + "Episodes Summary": "

Facebook moves fast because of vision, collaboration, and trust. The fast pace of development is enabled by constantly improving infrastructure and a sense of unity throughout the company. 

In Facebook’s early days, there was an emphasis on rapidly deploying new code to drive constant improvement and experimentation. 

Product quality was maintained by engineers closely checking each other’s code reviews, rather than writing detailed unit testing suites. Facebook engineers had a sense for how the product should operate, and they were able to evaluate whether a new feature was working properly by testing a live version of that feature.

At Facebook, the vision of the company is clearly communicated to the employees. Every employee within Facebook can articulate the vision for the company, and will use similar language in describing that vision. 

Since the employees are aligned on strategy, they can also align in their implementation of product features. This reduces conflicts across roles and between teams. 

Facebook has also shown a willingness to trust its engineers. Trust was exemplified by Facebook’s tolerance for failures in the early days. When an engineer broke a build, or shipped a feature that failed to gain traction, that engineer was usually not punished. They may have even been rewarded, if the company could learn significantly from such an error.

Raylene Yung was an engineer at Facebook from 2009 to 2015. As she moved from individual contributor to manager to engineering director, Raylene worked on products including News Feed, Timeline, Privacy, and Sharing. 

Raylene joins the show to give her reflections on the Facebook product and engineering environment. She explained how Facebook’s culture of collaboration, vision, and trust drive fast product development and minimizes conflict.

Raylene left Facebook and joined Stripe, where she worked on payments systems and international expansion for almost four years.

", + "Episodes Title": "Facebook Engineering Culture with Raylene Yung", + "Episodes Uid": "SED7306265772", + "Episodes Audio File": "d5f8cce8824fa0e1f31fc8709b374ca6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "29w", + "Episodes ID": "116e1626-e329-11ea-91a2-8339de3ec028", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/oldprogrammerreflections_edited.mp3", + "Episodes Pubdate Date": "2016-11-09", + "Episodes Summary": "

Ben Northrop was sitting at a tech conference, listening to a presentation about a new piece of technology, when he was struck by the sense that history was repeating itself. For the twenty years that Ben has worked as a software engineer, he has been hearing about new technologies that claim they will be able to disrupt everything, and he has relentlessly been keeping up as best he can with the latest trends.

Of course, Ben is all of us. Nobody can keep up. As a daily software podcaster, I think I am as well positioned as anyone to be tuned into the breadth of the software engineering ecosystem–but I am constantly behind as well.

In his blog post “Reflections of an Old Programmer”, Ben theorized about the causes of this feeling of fatigue, and the constant struggle to keep up with the world of software engineering. His post contains enduring lessons that will be of value to new programmers and will feel familiar to programmers who have been around for awhile.

", + "Episodes Title": "Reflections of an Old Programmer with Ben Northrop", + "Episodes Uid": "SED8230654435", + "Episodes Audio File": "8018454a1fd9315abb31eecdd09d9240.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25x", + "Episodes ID": "15514254-e329-11ea-91a2-6322c7c45a00", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Uber_DBs.mp3", + "Episodes Pubdate Date": "2016-09-09", + "Episodes Summary": "

When a company switches the relational database it uses, you wouldn’t expect the news of the switch to go viral. Most engineers are not interested in the subtle differences between MySQL and Postgres, right?

Uber recently switched from having Postgres as its main relational database to using MySQL. Evan Klitzke wrote a detailed blog post about the migration, and post got very popular for at least three reasons:

If you are even slightly interested in distributed systems or databases, I recommend reading Evan’s blog post in detail.

", + "Episodes Title": "Uber’s Postgres Problems with Evan Klitzke", + "Episodes Uid": "SED9948109390", + "Episodes Audio File": "67543bf12ec9a2ebe8f5a2be22cec0d6.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6d5", + "Episodes ID": "ebdb192c-e328-11ea-91a2-f78e11935878", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_25_Alluxio.mp3", + "Episodes Pubdate Date": "2019-10-25", + "Episodes Summary": "

In 2009, the Berkeley AMPLab was a center of innovation. 

Three projects from AMPLab have turned into successful open source projects and companies: Spark, Mesos, and Alluxio. Haoyuan Li was the creator of Alluxio, and he returns to the show to discuss his journey taking Alluxio from a research project to a company that has customers including Alibaba, Baidu, Wells Fargo, and Samsung.

Alluxio is a distributed, fault-tolerant, tiered storage system. Alluxio allows application developers to think in terms of the latency that they require from their infrastructure rather than the details of different storage systems. Haoyuan discusses the process of integrating with gigantic companies like cloud providers, telecoms, and huge ecommerce companies.

Alluxio is also hosting an upcoming conference, the Data Orchestration Summit November 7th at the Computer History Museum in Mountain View California.

November 7, 2019 is the first open source Data Orchestration Summit in the Computer History Museum in Mountain View, CA. The summit brings together data engineers, data platform engineers, and data scientists to share their challenges and learnings from building and using modern analytics, AI, and cloud technologies. Featuring tech talks covering use cases, demos, best practices, and tutorials by industry experts from EA, Walmart, DBS Bank, Netflix, AWS, Rakuten, Tencent, Google, Baidu, Alibaba and more, with a focus on how to build cloud native analytics & AI platforms. Use code “SDE” to get a 50% discount.

", + "Episodes Title": "Alluxio: Data Orchestration with Haoyuan Li", + "Episodes Uid": "SED1509605142", + "Episodes Audio File": "f8cfc8a6af382254583be7a7612791d5.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 6000000000, + "Episodes ID": "ebb49c52-e328-11ea-91a2-5b5811c8b326", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_06_FossaKevinWang.mp3", + "Episodes Pubdate Date": "2019-11-06", + "Episodes Summary": "

Every company has a software supply chain.

A company builds its products from custom code, paid APIs, paid proprietary binaries, and open source software libraries. As the types of software available have increased, the management of the software supply chain has become complex. 

Large software companies have always needed to ensure the security of their software. With the growing variety of open source licenses, these companies also have to deal with an increased set of legal complexities. If an open source project is used in a way that violates an open source license, the company is subject to legal risk.

FOSSA is a company that focuses on automating the management of open source compliance and security. Kevin Wang is the CEO of FOSSA, and he joins the show to discuss the modern issues of software licensing and his experience building a company.

", + "Episodes Title": "FOSSA: Open Source Management with Kevin Wang", + "Episodes Uid": "SED1248373851", + "Episodes Audio File": "ab9688b4f05cae676a6b79934cdee18b.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7d6", + "Episodes ID": "e8b0bc66-e328-11ea-91a2-7fd094f41f61", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_01_SnowplowAnalytics.mp3", + "Episodes Pubdate Date": "2020-07-01", + "Episodes Summary": "

As a user browses a webpage, that browser session generates events that need to be recorded, validated, enriched, and stored. This data is sometimes called customer data infrastructure, or CDI. This data requires a full stack of different tools: a system on the frontend to collect the data, middleware to transport the data, and backend systems for storing and loading that data into data warehouses and other analytical systems.

Snowplow Analytics is a data collection platform for storing events. In Snowplow, modules called Trackers send data to Collectors. The data can then be validated and enriched, and then put into the user’s data warehouse via ETL.

Alex Dean is the CEO of Snowplow, and he joins the show to talk through the business model, management, and engineering of Snowplow Analytics, as well as the overall data engineering landscape.

", + "Episodes Title": "Snowplow Analytics: Data Collection Platform with Alex Dean", + "Episodes Uid": "SED9483445754", + "Episodes Audio File": "04297cdd6e867bc6fe59362985ec3b69.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "72c", + "Episodes ID": "e9cd13d8-e328-11ea-91a2-c307f08ee8f1", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_10_ReservedAI.mp3", + "Episodes Pubdate Date": "2020-04-10", + "Episodes Summary": "

When a developer spins up a virtual machine on AWS, that virtual machine could be purchased using one of several types of cost structures. These cost structures include on-demand instances, spot instances, and reserved instances.

On-demand instances are often the most expensive, because the developer gets reliable VM infrastructure without committing to long-term pricing. Spot instances are cheap, spare compute capacity with lower reliability, that is available across AWS infrastructure. Reserved instances allow a developer to purchase longer term VM contracts for a lower price.

Reserved instances can provide significant savings, but it can be difficult to calculate how much infrastructure to purchase. Aran Khanna is the founder of Reserved.ai, a company that builds cost management tools for AWS. He joins the show to talk about the landscape of cost management, and what he is building with Reserved.ai.

", + "Episodes Title": "Reserved Instances with Aran Khanna", + "Episodes Uid": "SED2922626055", + "Episodes Audio File": "0d94948c561362f00e546949814c361f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1by", + "Episodes ID": "24d07d26-e329-11ea-91a2-fffc9506a34c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Lastmile_Edited.mp3", + "Episodes Pubdate Date": "2016-01-26", + "Episodes Summary": "

Incarceration in the United States is often a punitive exercise rather than a rehabilitative one. As a consequence, recidivism is the norm – according to a 2012 report by the California Department of Corrections and Rehabilitation, just over 65% of those released from California’s prison system return within three years. San Quentin State Prison in California is challenging this issue by trying to equip inmates with valuable skills while they are incarcerated.

The Last Mile is a program that works with prisoners to help them build relevant skills in technology so that they can more easily transition to productive employment once they are out of prison. Specifically, it teaches inmates how to program, oftentimes starting at the basics like how to use a computer, and how hypertext works. In addition to the challenges of teaching students who may not know computer basics, the program has to work with the constraint of not having internet access. In this episode, Wes and Jeff discuss the realities of incarceration in the United States, and how teaching inmates how to code is a remarkably empowering way to combat and weaken the prison-industrial complex.

Wes Bailey is the Director of Program Operations at The Last Mile, and a self-taught developer.

", + "Episodes Title": "Teaching Inmates to Code with Wes Bailey", + "Episodes Uid": "SED6196111945", + "Episodes Audio File": "8a74286d51308b3172ac303fbd2e862c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "72x", + "Episodes ID": "e9c8d6c4-e328-11ea-91a2-776cc9c6e071", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_13_CollaborativeSQLPopSQL.mp3", + "Episodes Pubdate Date": "2020-04-13", + "Episodes Summary": "

Data analysts need to collaborate with each other in the same way that software engineers do. They also need a high quality development environment. 

These data analysts are not working with programming languages like Java and Python, so they are not using an IDE such as Eclipse. Data analysts predominantly use SQL, and the tooling for a data analyst to work with SQL is often a SQL explorer tool that lacks the kind of collaborative experience that we would expect in the age of Slack and GitHub.

Rahil Sondhi is the creator of PopSQL, a collaborative SQL explorer. He created PopSQL after several years in the software industry, including 4 years at Instacart. Rahil joins the show to talk about the frictions that data analysts encounter when working with databases, and how those frictions led to the design of PopSQL.

", + "Episodes Title": "Collaborative SQL with Rahil Sondhi", + "Episodes Uid": "SED9264759948", + "Episodes Audio File": "97046a0ac5317ae894ccd9059e7067d4.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 113, + "Episodes ID": "2a9a9c14-e329-11ea-91a2-83e61c99a094", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Insight_Edited.mp3", + "Episodes Pubdate Date": "2015-12-02", + "Episodes Summary": "

Data engineering is a newly emerging field that exists at the intersection of software engineering and data science. Data engineers are increasingly in demand for their abilities to use the various open source big data frameworks to build efficient and robust data pipelines.

David Drummond and Austin Ouyang are program directors for the Insight Data Engineering Fellows Program, where they help train data engineers that can immediately start contributing in the industry.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Data Engineering with David Drummond and Austin Ouyang", + "Episodes Uid": "SED5017330087", + "Episodes Audio File": "831d8d5c17212adbf8d56971259e349a.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "28k", + "Episodes ID": "1296bad0-e329-11ea-91a2-875a79048740", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/cloudcasting_edited.mp3", + "Episodes Pubdate Date": "2016-10-19", + "Episodes Summary": "

Cloud computing was something much different in 2011, when Brian Gracely and Aaron Delp started The Cloudcast, a podcast I listen to on a regular basis. The Cloudcast features technical discussions about cloud infrastructure technology, and one of the most recent shows was a monologue by Brian Gracely where he explained his perspective on the industry rumblings about a Docker fork.

The utility of a container for so many different purposes leads to different organizations having differing preferences for what use case is optimized for. The impression that I took away from this conversation, as well as the next episode that will air with Joe Beda, is that the diverse opinions and products in the container and orchestration ecosystem is quite healthy.

Brian does a great job explaining his perspective on The Cloudcast, and he discusses his beliefs further in this episode.

", + "Episodes Title": "Docker Cloudcasting with Brian Gracely", + "Episodes Uid": "SED9719687560", + "Episodes Audio File": "11e5c63b23f7f8591588f8ead93ec1bd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "25c", + "Episodes ID": "15b2aaf8-e329-11ea-91a2-eb5162c2289d", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/wordsmith_edited.mp3", + "Episodes Pubdate Date": "2016-09-01", + "Episodes Summary": "

You have probably read a news article that was written by a machine. When earnings reports come out, or a series of sports events like the Olympics occurs, there are so many small stories that need to be written that a news organization like the Associated Press would have to use all of its resources to write enough content to cover it all.

Wordsmith is a tool for automated content generation, and today’s guest Robbie Allen is the CEO of Automated Insights, the company that makes Wordsmith. He talks today about the wide range of uses for automated content, as well as how to engineer a product that takes data from a spreadsheet and turns it into a human-readable sentence.

Robbie is also speaking at the O’Reilly Artificial Intelligence Conference in New York, September 26-27.

", + "Episodes Title": "Automated Content with Robbie Allen", + "Episodes Uid": "SED7087822402", + "Episodes Audio File": "385a812734c28f667e9236af58aac036.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7et", + "Episodes ID": "e8954f44-e328-11ea-91a2-23a7a388abc9", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_09_Chronosphere.mp3", + "Episodes Pubdate Date": "2020-07-09", + "Episodes Summary": "

M3 is a scalable metrics database originally built to host Uber’s rapidly growing data storage from Prometheus. When Rob Skillington was at Uber, he helped design, implement, and deploy M3. Since leaving Uber, he has co-founded a company around a hosted version of M3 called Chronosphere.

If you have access to a scalable metrics database, you might as well start accumulating as much data as possible, right? Not exactly. If your company generates enough data, you probably want to turn down the dials on how frequently you save a metric. Downsampling will reduce the amount of money that you pay for these hosted metrics.

In today’s show, Rob discusses the engineering and deployment of M3, and how that work led him to founding Chronosphere, as well as the product offering of the company.

", + "Episodes Title": "Chronosphere: Scalable Metrics Database with Rob Skillington", + "Episodes Uid": "SED8780593625", + "Episodes Audio File": "1326e308eff73fd11d6c4f2e247badc0.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5z3", + "Episodes ID": "ed133acc-e328-11ea-91a2-ff76acf219de", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_07_23_DataEngineeringwithTobias.mp3", + "Episodes Pubdate Date": "2019-07-23", + "Episodes Summary": "

The Hadoop ecosystem provided every company with the tools to store and query large amounts of data at a low cost. Since 2005, that ecosystem has expanded with more and more open source applications for data infrastructure. 

Data infrastructure includes databases, data lakes, distributed queues, data warehouses, query engines, web applications, on-prem software, closed source, open source, cloud platforms, and software-as-a-service. There is so much software, and it is difficult to keep track of everything in the data engineering ecosystem.

Tobias Macey is the host of the Data Engineering Podcast, a show about technologies and practices in the world of data engineering. Tobias joins today’s episode as a guest to give his perspective on the evolving landscape of data engineering, and the trends he is seeing on the data engineering podcast.

", + "Episodes Title": "Data Engineering with Tobias Macey", + "Episodes Uid": "SED1076854434", + "Episodes Audio File": "f6e862c3f9fe08de7a68273f58bf2a9e.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 692, + "Episodes ID": "ec384dc2-e328-11ea-91a2-d7d2a4f5f86c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_09_27_StripeInfrastructureUmaChingunde.mp3", + "Episodes Pubdate Date": "2019-09-27", + "Episodes Summary": "

Software engineering is a new field. There are theories about how we should be building our systems, but these theories might change over time. The same is true for engineering management. 

There are many successful examples of companies scaling with the management hierarchies pioneered by Microsoft and Google, but since everyone knows that those techniques work, they get continually copied. Of course, there is tremendous risk in pioneering a brand new management structure. There have been examples of successful software companies that have suffered tremendously due to a trial of an exciting new management structure.

New software is much easier and safer to try than revolutionary new management structures. New software is easier to try in a company with a strong engineering team, because that team is equipped to assess the new software and figure out if it is actually solving a problem that the company has. 

Uma Chingunde is an engineering manager at Stripe on the compute team. Uma has worked in management for a decade, and has worked in virtualization in infrastructure for even longer than that. Uma joins the show to give her perspective on management of engineers as well as management of compute infrastructure. We discussed some timeless principles of engineering management, as well as contemporary ideas around virtualization and compute.

", + "Episodes Title": "Stripe Infrastructure Management with Uma Chingunde", + "Episodes Uid": "SED3072975625", + "Episodes Audio File": "b0717415040a208f75d9a34396432d4c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 767, + "Episodes ID": "e96c29b0-e328-11ea-91a2-23ed6731e4bd", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_05_07_Pravega.mp3", + "Episodes Pubdate Date": "2020-05-07", + "Episodes Summary": "

“Data stream” is a word that can be used in multiple ways. A stream can refer to data in motion or data at rest. 

When a stream is data in motion, an endpoint is receiving new pieces of data on a continual basis. Each new data point is sent over the wire and captured by the other end. Another way a stream can be represented is as a sequence of events that have been written to a storage medium. This is a stream at rest.

Pravega is a system for storing large streams of data. Pravega can be used as an alternative to systems like Apache Kafka or Apache Pulsar. Flavio Junquiera is an engineer at Dell EMC who works on Pravega. He joins the show to talk about the history of stream processing and his work on Pravega.

", + "Episodes Title": "Pravega: Storage for Streams with Flavio Junquiera", + "Episodes Uid": "SED8335610285", + "Episodes Audio File": "91c84672ecaec4d980265148052da391.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "4yq", + "Episodes ID": "f0720f7c-e328-11ea-91a2-73c7dbb591ca", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/algorithms_edited.mp3", + "Episodes Pubdate Date": "2018-11-22", + "Episodes Summary": "

Originally posted on May 12, 2016.

When you are deciding who to marry, you are using an algorithm. The same is true when you are looking for a parking space, playing a game of poker, or deciding whether or not to organize your closet. Algorithms To Live By is a book about the computer science of human decisions. It offers strategies for how to think through everyday life like a computer scientist.

Brian Christian has a background in computer science and philosophy, and is an author of Algorithms to Live By. He joins the show to explain how the same algorithms and data structures we use for our computer programs can be applied to the real world.

", + "Episodes Title": "Algorithms to Live By with Brian Christian Holiday Repeat", + "Episodes Uid": "SED9678337535", + "Episodes Audio File": "7bc415b0ce6a3d545cbce3fc1164e8f8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 212, + "Episodes ID": "1aa3413a-e329-11ea-91a2-37b1dd887711", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Cimpress_Edited_2.mp3", + "Episodes Pubdate Date": "2016-06-22", + "Episodes Summary": "

Mass customization is the process of making customized, personalized products that are accessible to individuals and small businesses. The process involves manufacturing, assembly lines, supply chains, and software at every step along the way. Today’s guests are Jim Sokoloff and Maarten Wensveen, who work on infrastructure and technology at Cimpress, a mass customization platform.

Cimpress has t shirt printers, warehousing machines, supply chain management tools, and lots of other computers that come together in the computer-integrated manufacturing process. The company has been around for a few decades, and more recently they have moved to microservices for many of the reasons that have been discussed in previous episodes. If you work at a big company with some monolithic characteristics, this episode might give you some good arguments to bring to your manager about why and how to move to microservices.

", + "Episodes Title": "Manufacturing and Microservices with Cimpress’ Jim Sokoloff and Maarten Wensveen", + "Episodes Uid": "SED4232469863", + "Episodes Audio File": "e8bca03d32346196cb96d106bb99429f.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "70t", + "Episodes ID": "e9d5fe58-e328-11ea-91a2-af68dac09b0f", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_08_CadenceWorkflow_Orchestration.mp3", + "Episodes Pubdate Date": "2020-04-08", + "Episodes Summary": "

A workflow is an application that involves more than just a simple request/response communication. For example, consider a session of a user taking a ride in an Uber. The user initiates the ride, and the ride might last for an hour. At the end of the ride, the user is charged for the ride and sent a transactional email.

Throughout this entire ride, there are many different services and database tables being accessed across the Uber infrastructure. The transactions across this infrastructure need to be processed despite server failures which may occur along the way. 

Workflows are not just a part of Uber. Many different types of distributed operations at a company might be classified as a workflow: banking operations, spinning up a large cluster of machines, performing a distributed cron job.

Maxim Fateev is the founder of Temporal.io, and the co-creator of Cadence, a workflow orchestration engine. Maxim developed Cadence when he was at Uber, seeing the engineering challenges that come from trying to solve the workflow orchestration problem. Before Uber, Maxim worked at AWS on the Simple Workflow Service, which was also a system for running workflows. Altogether, Maxim has developed workflow software for more than a decade.

", + "Episodes Title": "Cadence: Uber’s Workflow Engine with Maxim Fateev", + "Episodes Uid": "SED9903878266", + "Episodes Audio File": "cac375c0630ad02dc4a3499368971e05.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "7h5", + "Episodes ID": "e8603e8a-e328-11ea-91a2-dfbe88e5eea9", + "Episodes Original URL": "https://traffic.libsyn.com/secure/sedaily/2020_07_24_HyperparameterTuning.mp3", + "Episodes Pubdate Date": "2020-07-24", + "Episodes Summary": "

Ray is a general purpose distributed computing framework. At a low level, Ray provides fault-tolerant primitives that support applications running across multiple processors. At a higher level, Ray supports scalable reinforcement learning, including the common problem of hyperparameter tuning.

In a previous episode, we explored the primitives of Ray as well as Anyscale, the business built around Ray and reinforcement learning. In today’s episode, Richard Liaw explores some of the libraries and applications that sit on top of Ray. 

RLlib gives APIs for reinforcement learning such as policy serving and multi-agent environments. Tune gives developers an easy way to do scalable hyperparameter tuning, which is necessary for exploring different types of deep learning configurations. In a future show, we will explore Tune in more detail.

", + "Episodes Title": "Ray Applications with Richard Liaw", + "Episodes Uid": "SED9516277974", + "Episodes Audio File": "d876c4c39ab7786920749644063e5a30.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "10l", + "Episodes ID": "2aca85aa-e329-11ea-91a2-ef83bcb78207", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/J-P_Edited_Version_2.mp3", + "Episodes Pubdate Date": "2015-12-01", + "Episodes Summary": "

This is episode 100 of Software Engineering Daily, and is a behind the scenes episode on the show that explores the challenges and motivations behind building a daily software podcast.

Pranay Mohan is the Producer of Software Engineering Daily.

", + "Episodes Title": "Episode 100 with Pranay Mohan", + "Episodes Uid": "SED4141108168", + "Episodes Audio File": "2575bc3a8643fd278d14a677911d2050.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ex", + "Episodes ID": "23a57d84-e329-11ea-91a2-479909761309", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/UX_Edited.mp3", + "Episodes Pubdate Date": "2016-02-09", + "Episodes Summary": "

In today’s episode of SEDaily, Jeff and Austin discuss why designing for a drunk user is a competitive advantage. Austin also explains why engineers need to think about UX and how they can incorporate UX considerations into development workflows.

Austin Knight is a designer and UX engineer at Hubspot.

Austin will be speaking at the upcoming Fluent Conference, and Software Engineering Daily is giving away a ticket to Fluent, which will be held March 8-10 in San Francisco. To be entered in a random drawing for this free ticket, tweet about your favorite episode of Software Engineering Daily between now and February 22nd. Make sure to tag us @software_daily and Fluent @fluentconf so we see your tweet.

", + "Episodes Title": "Designing for Drunk Users with Austin Knight", + "Episodes Uid": "SED4445140719", + "Episodes Audio File": "9e7070d6750e563169c86f791a2a972c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1yd", + "Episodes ID": "1d13d3ee-e329-11ea-91a2-cb8a2a304602", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Cassandra_Spark_Edited_2.mp3", + "Episodes Pubdate Date": "2016-05-11", + "Episodes Summary": "

Apache Spark is a framework for fast, distributed, in-memory analysis. Apache Cassandra is a distributed database management system that provides high availability and fast throughput. Today, we are collecting fast, big data streams from user behavior, smart phones and sensors, and the disk checkpointing of and query language of Hadoop MapReduce is no longer adequate.

Tim Berglund from Datastax came on Software Engineering Daily to explain how Apache Cassandra in a popular episode a few weeks ago. On this episode, Tim returns to discuss how Spark and Cassandra can be used together to provide a stack with the analytics and storage we need for today’s distributed computing environment.

", + "Episodes Title": "Spark and Cassandra with Tim Berglund", + "Episodes Uid": "SED4230947527", + "Episodes Audio File": "de40210c6bba3f2d25893782d5460b15.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1ps", + "Episodes ID": "20f5425e-e329-11ea-91a2-9f968ad83303", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Filodb_Edited.mp3", + "Episodes Pubdate Date": "2016-03-12", + "Episodes Summary": "

Big data is yesterday–fast data is now. FiloDB is a reactive columnar OLAP database that is built on Cassandra and Spark. Today’s guest is Evan Chan, creator of FiloDB.

In our discussion today, we talk about the use cases of an OLAP data store. Evan explains how to tackle the problem of video analytics–if you have ever found yourself asking how a company like YouTube or Netflix or Ooyala performs analytics on millions of users watching millions of videos, this episode is for you. By combining the database features of Cassandra with the data processing power of Spark, Evan created FiloDB to help solve this type of analytics problem. Evan will also be presenting at Strata + Hadoop World in San Jose. We’re partnering with O’Reilly to support this conference – if you want to go to Strata, you can save 20% off a ticket with our code PCSED.

", + "Episodes Title": "FiloDB with Evan Chan", + "Episodes Uid": "SED2834688775", + "Episodes Audio File": "006425b158f97248b2f773f9a57bdd69.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 130, + "Episodes ID": "29c77a1e-e329-11ea-91a2-23744766bac5", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Learning_101_Edited.mp3", + "Episodes Pubdate Date": "2015-12-08", + "Episodes Summary": "

Richard Golden is the host of Learning Machines 101, a podcast that covers artificial intelligence and machine learning topics. Dr. Golden is also a full-time Professor of Cognitive Science and Electrical Engineering at UT Dallas.

Hired.com is the job marketplace for software engineers. Go to hired.com/softwareengineeringdaily to get a $600 bonus upon landing a job through Hired.

Digital Ocean is the simplest cloud hosting provider. Use promo code SEDAILY for $10 in free credit.

", + "Episodes Title": "Learning Machines with Richard Golden", + "Episodes Uid": "SED5742831075", + "Episodes Audio File": "0ef222f0e763e7a4b162ad524e361e60.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2dh", + "Episodes ID": "0d2193f4-e329-11ea-91a2-137b9ac1d75a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/monitoring_edited.mp3", + "Episodes Pubdate Date": "2016-12-27", + "Episodes Summary": "

Application performance monitoring helps an engineer understand what is going on with an application. An application on a single machine is often monitored by inserting bytecode instructions into the application after it has been interpreted. Distributed cloud applications with functionality broken up across multiple servers often use distributed tracing.

Andi Grabner from Dynatrace joins today’s show to explain how monitoring software is built, and how engineers use it to solve problems. Monitoring is core to every business, whether the goal is to understand top-level business processes of to dissect and debug a specific engineering problem. And because monitoring is important at every layer of the stack, there is a plethora of monitoring tools for sale.

", + "Episodes Title": "Performance Monitoring with Andi Grabner", + "Episodes Uid": "SED4496257304", + "Episodes Audio File": "299524d06f162c36d5f8795cd546cbe3.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1cb", + "Episodes ID": "248ab7be-e329-11ea-91a2-3b1fbd659131", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Opengov_Edited.mp3", + "Episodes Pubdate Date": "2016-01-28", + "Episodes Summary": "

Software is changing every domain including Marketing, Healthcare, and even Agriculture. Government is one specific area where the potential for improvement is obvious. Governments are often defined by abstract rules, transactions, permissions and hierarchies, grounded on some fundamental principles – this is striking similar to the same tenets that software and computer science are based on. In that sense, could software be leveraged in this unique industry to create massive change?

OpenGov is one company trying to find out through application of software in local city and state governments. The company currently offers a web-based financial visualization software that focuses on making government budget and financial data accessible by modeling and presenting it in a user-friendly way. But it is not farfetched to see the potential being greater and broader in scope. In this episode, Jeff discussed with Andrew how OpenGov is using technology to improve government. Their conversation focuses in on the front-end technologies used to create the webapp, as well as “microservice fatigue” and the other various architectural concerns within the team.

Andrew Clark is a software engineer at OpenGov.

", + "Episodes Title": "OpenGov with Andrew Clark", + "Episodes Uid": "SED3322874791", + "Episodes Audio File": "e4560003664d2abbaf86a2cf467515ea.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6bt", + "Episodes ID": "ebd69302-e328-11ea-91a2-cb079eb49641", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_10_28_FBJeffRothschildEntrepreneurship.mp3", + "Episodes Pubdate Date": "2019-10-28", + "Episodes Summary": "

Jeff Rothschild was one of the earliest engineers to join Facebook. In the 1990s, Jeff had co-founded Veritas Software and helped it to its IPO in 2004. After Veritas, Jeff worked on several other of his own companies. He was working with Accel Partners on investments when he started to learn about Facebook.

Accel was an investor in Facebook, having made a large investment in 2005. After the investment, Jeff was helping the company with hiring. As Facebook built out its senior engineering leadership, Jeff realized that he would enjoy working with the company in a more active role.

For the next ten years, Jeff Rothschild worked as a VP of infrastructure software at Facebook. He helped scale the company’s infrastructure and architect the technical strategy. By 2005, Jeff’s entrepreneurial background included software companies ranging from storage management to gaming. His diverse skill set was useful for setting product direction as well as solving novel engineering problems.

Jeff joins the show to discuss the early days of Facebook and his philosophy of entrepreneurship.

", + "Episodes Title": "Facebook Entrepreneurship with Jeff Rothschild", + "Episodes Uid": "SED2908165640", + "Episodes Audio File": "4ff0e13286e301fe9154730578788f22.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6hn", + "Episodes ID": "eb44c97c-e328-11ea-91a2-273894b5633a", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_12_09_PracticalAI.mp3", + "Episodes Pubdate Date": "2019-12-09", + "Episodes Summary": "

Machine learning algorithms have existed for decades. But in the last ten years, several advancements in software and hardware have caused dramatic growth in the viability of applications based on machine learning.

Smartphones generate large quantities of data about how humans move through the world. Software-as-a-service companies generate data about how these humans interact with businesses. Cheap cloud infrastructure allows for the storage of these high volumes of data. Machine learning frameworks such as Apache Spark, TensorFlow, and PyTorch allow developers to easily train statistical models.

These models are deployed back to the smartphones and the software-as-a-service companies, which improves the ability for humans to move through the world and gain utility from their business transactions. And as the humans interact more with their computers, it generates more data, which is used to create better models, and higher consumer utility.

The combination of smartphones, cloud computing, machine learning algorithms, and distributed computing frameworks is often referred to as “artificial intelligence.” Chris Benson is the host of the podcast Practical AI, and he joins the show to talk about the modern applications of artificial intelligence, and the stories he is covering on Practical AI. On his podcast, Chris talks about everything within the umbrella of AI, from high level stories to low level implementation details.

", + "Episodes Title": "Practical AI with Chris Benson", + "Episodes Uid": "SED6034031006", + "Episodes Audio File": "f4b8c97deb2ad8f017f0e2a340004392.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6dx", + "Episodes ID": "ebb8e51e-e328-11ea-91a2-e7245897bbc6", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_11_05_ScaleAPI.mp3", + "Episodes Pubdate Date": "2019-11-05", + "Episodes Summary": "

Machine learning is widely understood by the software community. But it is still hard to build a company around machine learning, because there is not easy access to large, unique data sets.

Scale is a platform for training and validating data that is used for machine learning.

Most machine learning models are built with supervised learning. Labeled examples are analyzed to understand the mathematical correlations between those labels. The more labeled training examples there are, the more accurate the correlations will be. 

Today, we have high quality frameworks for writing the models. We have cheap cloud computing for training and deploying the models. The biggest factor that is preventing a wide variety of potential machine learning applications from existing is lack of access to large, labeled data sets.

Scale gives developers an API for labeling images, sound, natural language, and video. Scale is used by self-driving car companies, Airbnb, OpenAI, retailers, and robotics companies. The product is used broadly and at high volume. Scale was started only three years ago, and recently raised $100m at a valuation above $1b, making it one of the fastest growing software companies in history.

Alexandr Wang joins the show to discuss how Scale works, the future of machine learning, and the future of work. He also describes the complexities of building Scale, and how he manages his own psychological state.

", + "Episodes Title": "Scale with Alexandr Wang", + "Episodes Uid": "SED4536109151", + "Episodes Audio File": "de46c13ab36e0126c288cd76d256e5b8.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": 743, + "Episodes ID": "e9a9b622-e328-11ea-91a2-6f94feadb0d8", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_04_22_NGINXAPIGateway.mp3", + "Episodes Pubdate Date": "2020-04-22", + "Episodes Summary": "

NGINX is a web server that can be used to manage the APIs across an organization. Managing these APIs involves deciding on the routing and load balancing across the servers which host them. If the traffic of a website suddenly spikes, the website needs to spin up new replica servers and update the API gateway to route traffic to those new replicas.

Some servers should not be accessible to outside traffic, and policy management is used to configure the security policies of different APIs. And as a company grows, the number of APIs also grows, increasing the complexity of managing routing logic and policies.

Kevin Jones is a product manager with NGINX. He joins the show to discuss how API management has changed with the growth of cloud and mobile, and how NGINX has evolved over that period of time. Full disclosure: NGINX is a sponsor of Software Engineering Daily.

", + "Episodes Title": "NGINX API Management with Kevin Jones", + "Episodes Uid": "SED7795133673", + "Episodes Audio File": "7f475868935a22e299db561c3bee6733.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1gy", + "Episodes ID": "23108f30-e329-11ea-91a2-5b2b4ca45b5c", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Reactiveprogramming_Edited.mp3", + "Episodes Pubdate Date": "2016-02-16", + "Episodes Summary": "

Reactive programming emphasizes writing code that is readily responsive to events. It is an increasingly popular paradigm with highly interactive websites like Netflix. It draws on the value of functional programming calls like map, reduce, and flatmap.

Matt joins us today to chat about reactive programming, the observer pattern, and his thoughts on where the future is going. If you are a fan of functional programming or JavaScript, you will enjoy this show. Matt is also speaking at the 2016 O’Reilly Fluent Conference. If you want to win a free ticket to the conference, tweet about your favorite episode of Software Engineering Daily and tag @fluentconf and @software_daily.

Matt Podwysocki is the author ReactiveX JS and a software engineer at Microsoft.

", + "Episodes Title": "Reactive Programming with Matthew Podwysocki", + "Episodes Uid": "SED6417028798", + "Episodes Audio File": "28e4aa75b77af44839c7352623dcc29c.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "2at", + "Episodes ID": "100d97f2-e329-11ea-91a2-eb6bd1bda836", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/microservices_tools_edited.mp3", + "Episodes Pubdate Date": "2016-11-22", + "Episodes Summary": "

Microservices are a widely adopted pattern for breaking an application up into pieces that can be well-understood by the individual teams within the company. Microservices also allow these individual pieces to be scaled independently and updated in isolation.

Past Software Engineering Daily episodes have covered the microservice architectures of Twitter, Netflix, Google, Uber and other companies. In today’s episode, I sit down with Rafael Schloming, who is building tools for microservices at Datawire.

", + "Episodes Title": "Microservices with Rafi Schloming", + "Episodes Uid": "SED5972213147", + "Episodes Audio File": "5c5e10a92ed488067e772a7f5b7fe98d.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1zl", + "Episodes ID": "1c30051a-e329-11ea-91a2-5ff8b6861839", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Wunder_Capital_Edited.mp3", + "Episodes Pubdate Date": "2016-05-27", + "Episodes Summary": "

Solar energy is a growing market. Improvements in hardware have led to some people predicting that solar energy will be powering the world within the next few decades. Undoubtedly, a large percentage of our current energy infrastructure will be replaced by solar in the near future. Replacing our old, inefficient power grid requires massive investment.

On Software Engineering Daily, the resources we usually talk about are memory, bandwidth, storage, and other computer science concepts. David Reiss joins us today to talk about energy, which is a resource so fundamental that we usually don’t even consider it. David is the CTO of Wunder Capital, a fintech company that facilitates investments in solar power.

Much of this conversation centers on the economics of the solar energy market, but we also discuss software topics–machine learning and why Wunder Capital’s software architecture is a monolith by design today.

Sponsors

", + "Episodes Title": "Solar Investment and Architectural Strategy at Wunder Capital", + "Episodes Uid": "SED7364675335", + "Episodes Audio File": "7be031444c3abb851d9b3b241e7d05bd.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "6o9", + "Episodes ID": "eabc52c2-e328-11ea-91a2-fb52df64d342", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2020_01_31_VentureCapitalwithErikTorenberg.mp3", + "Episodes Pubdate Date": "2020-01-31", + "Episodes Summary": "

Venture capital investing requires an understanding of market dynamics, technology, and finance. 

There is also an element of human nature. Consumer trends can make or break the viability of a new product. And early stage venture investing is always a bet on a small team or individual founder. Early stage investments are usually into companies that have not found perfect traction with their product. Judging the worth of an early stage investment means judging the likelihood that the founders can make their vision a reality.

Venture Stories is a podcast that explores the wide spectrum of ideas that go into venture investing. Shows include two person interviews on economics, social networking, food technology, cryptocurrencies, and consumer psychology.

Erik Torenberg is a co-founder and partner of Village Global, an early stage venture capital firm. He is also the host of Venture Stories. Erik joins the show to discuss investing, media, and the kinds of new technology companies that are being created today.

", + "Episodes Title": "Venture Stories with Erik Torenberg", + "Episodes Uid": "SED2602467839", + "Episodes Audio File": "3ef432bcc9b1e4423431da6783b6b8c2.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "1c5", + "Episodes ID": "24bac562-e329-11ea-91a2-b37158d3b2e3", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/Mesosphere_Edited.mp3", + "Episodes Pubdate Date": "2016-01-27", + "Episodes Summary": "

In this episode, Jeff and Derrick sit down to discuss the state of tech journalism, and how it has kept up with the rapid pace of technology innovation. Additionally, they discuss the evolution of the “big data” stack and where it is headed. The conversation focuses in on Apache Mesos and Mesosphere, the company building the Datacenter Operating System (DCOS).

Derrick Harris is a long time tech journalist, having worked at GigaOm and Fortune as a writer covering tech topics. He currently works at Mesosphere, where he is a tech evangelist.

", + "Episodes Title": "Mesosphere and Tech Journalism with Derrick Harris", + "Episodes Uid": "SED3820128765", + "Episodes Audio File": "ac3a5f197f22a4cff577e2a30a2430df.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + }, + { + "Podcasts RSS Feed": "https://feeds.megaphone.fm/SED4843981401", + "Podcasts Summary": "

Technical interviews about software topics.

", + "Podcasts Title": "Software Daily", + "Podcasts Uid": "SED4843981401", + "Podcasts Imported URL": "https://software-enginnering-daily-api.herokuapp.com/api/rss/public/all_unlimited", + "Podcasts Created Date": "2020-08-20", + "Episodes Guid": "5g7", + "Episodes ID": "eec387aa-e328-11ea-91a2-9f6b417e2590", + "Episodes Original URL": "http://traffic.libsyn.com/sedaily/2019_03_12_UberPeloton.mp3", + "Episodes Pubdate Date": "2019-03-28", + "Episodes Summary": "

Upcoming events:

A Conversation with Haseeb Qureshi at Cloudflare on April 3, 2019

FindCollabs Hackathon at App Academy on April 6, 2019

Google’s Borg system is a cluster manager that powers the applications running across Google’s massive infrastructure. Borg provided inspiration for open source tools like Apache Mesos and Kubernetes.

Over the last decade, some of the largest new technology companies have built their own systems that fulfill the roles of cluster management and resource scheduling. Netflix, Twitter, and Facebook have all spoken about their internal projects to make distributed systems resource allocation more economical. These companies find themselves continually reinventing scheduling and orchestration, with inspiration from Google Borg and their own internal experiences running large numbers of containers and virtual machines.

Uber’s engineering team has built a cluster scheduler called Peloton. Peloton is based on Apache Mesos, and is architected to handle a wide range of workloads: data science jobs like Hadoop MapReduce; long running services such as a ridesharing marketplace service; monitoring daemons such as Uber’s M3 collector; and database services such as MySQL.

Min Cai and Mayank Bansal are engineers at Uber who work on Peloton. When they set out to create Peloton, they looked at the existing schedulers in the ecosystem, including Kubernetes, Mesos, Hadoop’s YARN system, and Borg itself.

Both Min and Mayank join the show today to give a brief history of distributed systems schedulers and discuss their work on Peloton. They have been working in the world of distributed systems schedulers for many years–including experiences building core Hadoop infrastructure and virtual machine schedulers at VMware.

", + "Episodes Title": "Peloton: Uber’s Cluster Scheduler with Min Cai and Mayank Bansal", + "Episodes Uid": "SED6805484716", + "Episodes Audio File": "c1dffc28bf2df4d29e4d62612eb67be9.mp3", + "Episodes Author": "", + "Podcasts Author": "SoftwareDaily.com", + "Podcasts Category": "", + "Podcasts iTunes Category": "News" + } + ] +} diff --git a/migrations/1588964716270-multiple-topic-maintainers.js b/migrations/1588964716270-multiple-topic-maintainers.js new file mode 100644 index 00000000..6a6c69f3 --- /dev/null +++ b/migrations/1588964716270-multiple-topic-maintainers.js @@ -0,0 +1,57 @@ +import mongoose from 'mongoose'; +import Topic from '../server/models/topic.model'; +import User from '../server/models/user.model'; // eslint-disable-line +import config from './../config/config'; + +// make bluebird default Promise +Promise = require('bluebird'); // eslint-disable-line no-global-assign + +// eslint-disable-next-line +module.exports.up = function (next) { + // plugin bluebird promise in mongoose + mongoose.Promise = Promise; + mongoose.connect(config.mongo.host, { useMongoClient: true }); + + const db = mongoose.connection; + + db.once('open', () => { + Topic + .find({ + maintainer: { $exists: true }, + maintainers: { $exists: false }, + }) + .exec() + .then((topics) => { + const promises = []; + + topics.forEach((topic) => { + if (topic._id && topic.maintainer) { + promises.push(Topic + .findByIdAndUpdate(topic._id, { + $set: { + maintainers: [topic.maintainer] + } + }) + .exec()); + } + }); + + return Promise.all(promises).then(Promise.resolve); + }) + .then(() => { + db.close(); + next(); + return Promise.resolve(); + }) + .catch((err) => { + db.close(); + next(err); + return Promise.resolve(); + }); + }); +}; + +// eslint-disable-next-line +module.exports.down = function (next) { + next(); +}; diff --git a/migrations/1589311757761-index-topics.js b/migrations/1589311757761-index-topics.js new file mode 100644 index 00000000..3eabacf4 --- /dev/null +++ b/migrations/1589311757761-index-topics.js @@ -0,0 +1,112 @@ +import mongoose from 'mongoose'; +import omit from 'lodash/omit'; +import flatten from 'lodash/flatten'; +import algoliasearch from 'algoliasearch'; +import TopicPage from '../server/models/topicPage.model'; +import Question from '../server/models/question.model'; +import Answer from '../server/models/answer.model'; // eslint-disable-line +import config from './../config/config'; + +// make bluebird default Promise +Promise = require('bluebird'); // eslint-disable-line no-global-assign + +function indexTopic(topicId) { + const client = algoliasearch( + process.env.ALGOLIA_APP_ID, + process.env.ALGOLIA_API_KEY, + ); + + const index = client.initIndex(process.env.ALGOLIA_TOPICS_INDEX); + + return TopicPage + .findOne({ topic: topicId }) + .populate('topic') + .exec() + .then((topicPage) => { + return Question + .find({ entityId: topicId }) + .populate('answers') + .then((questions) => { + let answers = questions + .filter(q => q.answers.length) + .map((q) => { + return q.answers.map(a => a.content); + }); + + answers = flatten(answers); + + const _topicPage = topicPage.toObject(); + const slug = (_topicPage.topic && _topicPage.topic.slug) ? _topicPage.topic.slug : ''; + const objectID = _topicPage.searchIndex; + const updateObject = { + ...omit(_topicPage, [ + 'history', + '__v', + 'images', + 'searchIndex', + ]), + slug, + answers, + }; + + if (updateObject.topic && updateObject.topic.name) { + updateObject.topic = updateObject.topic.name; + updateObject._title = updateObject.topic; + } + + if (objectID) { + updateObject.objectID = objectID; // eslint-disable-line + } + + return index + [objectID ? 'saveObject' : 'addObject'](updateObject) // eslint-disable-line + .then((content) => { // eslint-disable-line + return TopicPage + .updateOne({ _id: topicPage._id }, { $set: { searchIndex: content.objectID } }) + .then(Promise.resolve); + }); + }); + }); +} + +// eslint-disable-next-line +module.exports.up = function (next) { + // plugin bluebird promise in mongoose + mongoose.Promise = Promise; + mongoose.connect(config.mongo.host, { useMongoClient: true }); + + const db = mongoose.connection; + + db.once('open', () => { + TopicPage + .find({ + searchIndex: { $exists: false }, + published: true, + }) + .exec() + .then((topicPages) => { + const promises = []; + + topicPages.forEach((topicPage) => { + promises.push(indexTopic(topicPage.topic)); + }); + + return Promise.all(promises).then(Promise.resolve); + }) + .then(() => { + db.close(); + next(); + return Promise.resolve(); + }) + .catch((err) => { + db.close(); + next(err); + return Promise.resolve(); + }); + }); +}; + +// eslint-disable-next-line +module.exports.down = function (next) { + next(); +}; diff --git a/package-lock.json b/package-lock.json index 38a00e11..b1b83452 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,594 +1,1041 @@ { "name": "software-engineering-daily-api", "version": "2.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, - "dependencies": { - "@gulp-sourcemaps/identity-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz", - "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", - "requires": { - "acorn": "5.1.2", - "css": "2.2.1", - "normalize-path": "2.1.1", - "source-map": "0.5.7", - "through2": "2.0.3" + "packages": { + "": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "@sendgrid/mail": "^6.1.4", + "@sentry/node": "^5.17.0", + "algoliasearch": "^3.35.1", + "async": "^3.1.1", + "aws-sdk": "^2.150.0", + "axios": "^0.19.0", + "babel-cli": "6.26.0", + "babel-core": "6.26.0", + "babel-plugin-add-module-exports": "0.2.1", + "babel-preset-es2015": "6.24.1", + "babel-preset-stage-2": "6.24.1", + "bcrypt-nodejs": "0.0.3", + "bluebird": "3.5.0", + "body-parser": "1.17.2", + "chai": "4.1.2", + "commitizen": "2.9.6", + "compression": "1.7.0", + "cookie-parser": "1.4.3", + "cors": "2.8.4", + "coveralls": "2.13.1", + "cron": "1.8.2", + "cross-env": "5.0.5", + "cz-conventional-changelog": "2.0.0", + "debug": "3.0.1", + "del": "3.0.0", + "dotenv": "4.0.0", + "eslint": "4.6.1", + "eslint-config-airbnb-base": "12.0.0", + "eslint-plugin-import": "2.7.0", + "eslint-watch": "3.1.2", + "express": "^4.17.1", + "express-jwt": "^5.3.1", + "express-validation": "1.0.2", + "express-winston": "2.4.0", + "gulp": "3.9.1", + "gulp-babel": "7.0.0", + "gulp-load-plugins": "1.5.0", + "gulp-newer": "1.3.0", + "gulp-nodemon": "^2.4.2", + "gulp-sourcemaps": "2.6.1", + "gulp-util": "3.0.8", + "handlebars": "^4.7.3", + "helmet": "^3.21.1", + "http": "^0.0.1-security", + "http-proxy-middleware": "^1.0.6", + "http-status": "1.0.1", + "https": "^1.0.0", + "https-proxy-agent": "^4.0.0", + "istanbul": "1.0.0-alpha.2", + "joi": "10.6.0", + "jsdom": "^16.2.0", + "jsonwebtoken": "8.0.0", + "jstoxml": "^1.6.7", + "lodash": "^4.17.15", + "method-override": "2.3.9", + "migrate": "^1.6.2", + "mocha": "3.5.0", + "moment": "^2.24.0", + "mongodb": "^3.1.13", + "mongoose": "4.11.10", + "mongoose-slug-generator": "^1.0.4", + "mongoose-unique-validator": "^2.0.2", + "morgan": "^1.9.1", + "multer": "^1.3.0", + "page-metadata-parser": "^1.1.4", + "passport": "0.4.0", + "passport-facebook-token": "3.3.0", + "qs-mongodb": "^0.1.0", + "randomstring": "^1.1.5", + "recaptcha2": "^1.3.2", + "request": "^2.88.2", + "run-sequence": "2.1.0", + "sendgrid": "^5.2.3", + "socket.io": "^2.3.0", + "stripe": "^5.3.0", + "supertest": "3.0.0", + "supertest-as-promised": "4.0.2", + "swagger-jsdoc": "^1.9.7", + "twitter-lite": "^0.13.0", + "url": "^0.10.3", + "validate-commit-msg": "2.14.0", + "winston": "2.3.1" + }, + "devDependencies": { + "babel-polyfill": "^6.26.0", + "husky": "^0.14.3", + "lint-staged": "^6.0.0", + "minimist": "^1.2.0", + "sinon": "^4.2.2", + "sinon-mongoose": "^2.0.2", + "swagger-node-express": "^2.1.3" + }, + "engines": { + "node": "10.19.0", + "npm": "^6.13.4" } }, - "@gulp-sourcemaps/map-sources": { + "node_modules/@gulp-sourcemaps/identity-map": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", + "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==", + "dependencies": { + "acorn": "^5.0.3", + "css": "^2.2.1", + "normalize-path": "^2.1.1", + "source-map": "^0.6.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@gulp-sourcemaps/identity-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@gulp-sourcemaps/map-sources": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", - "requires": { - "normalize-path": "2.1.1", - "through2": "2.0.3" + "dependencies": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" } }, - "@sendgrid/client": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-6.2.1.tgz", - "integrity": "sha512-FLqoh2UqmFs5R/92xzF1jYMLGU89rTgLK6XX+VA02YcfQW8rGjbMrj7zsSCQ7SLkeiWekmUU2+naeIO9L4dqxA==", - "requires": { - "@sendgrid/helpers": "6.2.1", - "@types/request": "2.47.0", - "request": "2.83.0" + "node_modules/@sendgrid/client": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-6.3.0.tgz", + "integrity": "sha512-fTy8vRpA9Whtf8ULQr/0vkSZaQvGQ97rY5N5PrevKRtugJMsJqFMKO0pwzEWeqITSg71aMMTj57QTgw3SjZvnQ==", + "dependencies": { + "@sendgrid/helpers": "^6.3.0", + "@types/request": "^2.0.3", + "request": "^2.81.0" }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@sendgrid/helpers": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-6.3.0.tgz", + "integrity": "sha512-uTFcmhCDFg/2Uhz+z/cLwyLHH0UsblG49hKwdR7nKbWsGKWv4js7W32FlPdXqy2C/plTJ20vcPLgKM1m3F/MjQ==", "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "boom": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", - "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", - "requires": { - "hoek": "4.2.1" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "cryptiles": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", - "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", - "requires": { - "boom": "5.2.0" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "requires": { - "hoek": "4.2.1" - } - } - } - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.6", - "mime-types": "2.1.17" - }, - "dependencies": { - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "requires": { - "delayed-stream": "1.0.0" - } - } - } - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "requires": { - "ajv": "5.2.2", - "har-schema": "2.0.0" - } - }, - "hawk": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", - "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.1", - "sntp": "2.1.0" - } - }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" - } - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" - }, - "request": { - "version": "2.83.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", - "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "sntp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", - "requires": { - "hoek": "4.2.1" - } - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "5.1.1" - } - } + "chalk": "^2.0.1", + "deepmerge": "^2.1.1" + }, + "engines": { + "node": ">= 6.0.0" } }, - "@sendgrid/helpers": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-6.2.1.tgz", - "integrity": "sha512-WnQ4TV51Xln/X70lk6J1/3tfRHW3K4zagz19vlJrtQUtX1wwghOj926OqcMm5nOiBHEh+la3cvdzHENb09FsIA==", - "requires": { - "chalk": "2.3.2" + "node_modules/@sendgrid/mail": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-6.3.1.tgz", + "integrity": "sha512-5zIeAV9iU+0hQkrOQ/D4RB2MfpK+lNbOortIfQdCh95aMDF/TRc9WB8FGNhmQrx9YMuJTms5eiBklF0Fi/dbVg==", + "dependencies": { + "@sendgrid/client": "^6.3.0", + "@sendgrid/helpers": "^6.3.0" }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@sentry/apm": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/apm/-/apm-5.17.0.tgz", + "integrity": "sha512-raJcPa04TP8mVocSTHe0PdULpRWhw0NaLq9Rk8KCTFBJvLsgzY2krph5/LgEfBBX78vWt70FrwSw+DdIfYIJ6g==", "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "1.9.0" - } - }, - "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "requires": { - "has-flag": "3.0.0" - } - } + "@sentry/browser": "5.17.0", + "@sentry/hub": "5.17.0", + "@sentry/minimal": "5.17.0", + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" } }, - "@sendgrid/mail": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-6.2.1.tgz", - "integrity": "sha512-gTd8gMp4JVLGZhXb/DkyrjByTfIR1OvtpPpQLwO11Vz72x3JdPl4tJTtWA/svAFfN5UXnZtAomAvjJCdcd4lzw==", - "requires": { - "@sendgrid/client": "6.2.1", - "@sendgrid/helpers": "6.2.1" + "node_modules/@sentry/browser": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.17.0.tgz", + "integrity": "sha512-++pXpCHtdek1cRUwVeLvlxUJ2w1s+eiC9qN1N+7+HdAjHpBz2/tA1sKBCqwwVQZ490Cf2GLll9Ao7fuPPmveRQ==", + "dependencies": { + "@sentry/core": "5.17.0", + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" } }, - "@sinonjs/formatio": { + "node_modules/@sentry/core": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.17.0.tgz", + "integrity": "sha512-Kfx4rGKDC7V1YJjTGJXyl12VVHxM8Cjpu61YOyF8kXoXXg9u06C3n0G1dmfzLQERKXasUVMtXRBdKx/OjYpl1g==", + "dependencies": { + "@sentry/hub": "5.17.0", + "@sentry/minimal": "5.17.0", + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.17.0.tgz", + "integrity": "sha512-lyUbEmshwaMYdAzy4iwgizgvKODVVloB2trnefpq90AuWCdvzcxMLIGULx1ou+KohccqdNorYICKWeuRscKq5A==", + "dependencies": { + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.17.0.tgz", + "integrity": "sha512-v8xfkySXKrliZO6er6evlVe/ViUcqN0O8BhGyauK28Mf+KnKEOs5W6oWbt4qCDIttw9ynKIYyRrkAl/9oUR76A==", + "dependencies": { + "@sentry/hub": "5.17.0", + "@sentry/types": "5.17.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.17.0.tgz", + "integrity": "sha512-gaM+LNjQc7Wm+RG4f7KGZ/+An8RQ9/8CkJDB/DP4qwufsaIrcg1dZa6KeAUnh3KaXZ+ZuPji+agCIV/AQU4x8g==", + "dependencies": { + "@sentry/apm": "5.17.0", + "@sentry/core": "5.17.0", + "@sentry/hub": "5.17.0", + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "cookie": "^0.3.1", + "https-proxy-agent": "^4.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/types": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.17.0.tgz", + "integrity": "sha512-1z8EXzvg8GcsBNnSXgB5/G7mz2PwmMt9mjOrVG1jhtSGH1c7WvB32F5boqoMcjIJmy5MrBGaaXwrF/RRJrwUQg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.17.0.tgz", + "integrity": "sha512-qn8WgZcSkV/rx0ezp9q/xFjP7aMaYZO1/JYLXV4o6pYrQ9tvMmmwAZT39FpJunhhbkR36WNEuRB9C2K250cb/A==", + "dependencies": { + "@sentry/types": "5.17.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", + "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/formatio": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", "dev": true, - "requires": { + "dependencies": { "samsam": "1.3.0" } }, - "@types/caseless": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz", - "integrity": "sha512-FhlMa34NHp9K5MY1Uz8yb+ZvuX0pnvn3jScRSNAb75KHGB8d3rEU6hqMs3Z2vjuytcMfRg6c5CHMc3wtYyD2/A==" + "node_modules/@sinonjs/samsam": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.0.tgz", + "integrity": "sha512-beHeJM/RRAaLLsMJhsCvHK31rIqZuobfPLa/80yGH5hnD8PV1hyh9xJBJNFfNmO7yWqm+zomijHsXpI6iTQJfQ==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash": "^4.17.11" + } }, - "@types/form-data": { + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "node_modules/@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dependencies": { + "defer-to-connect": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@types/caseless": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", + "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + }, + "node_modules/@types/form-data": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", - "requires": { - "@types/node": "9.4.6" + "dependencies": { + "@types/node": "*" } }, - "@types/node": { - "version": "9.4.6", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.4.6.tgz", - "integrity": "sha512-CTUtLb6WqCCgp6P59QintjHWqzf4VL1uPA27bipLAPxFqrtK1gEYllePzTICGqQ8rYsCbpnsNypXjjDzGAAjEQ==" + "node_modules/@types/http-proxy": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz", + "integrity": "sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q==", + "dependencies": { + "@types/node": "*" + } }, - "@types/request": { - "version": "2.47.0", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.47.0.tgz", - "integrity": "sha512-/KXM5oev+nNCLIgBjkwbk8VqxmzI56woD4VUxn95O+YeQ8hJzcSmIZ1IN3WexiqBb6srzDo2bdMbsXxgXNkz5Q==", - "requires": { - "@types/caseless": "0.12.1", - "@types/form-data": "2.2.1", - "@types/node": "9.4.6", - "@types/tough-cookie": "2.3.2" + "node_modules/@types/node": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.4.tgz", + "integrity": "sha512-02tIL+QIi/RW4E5xILdoAMjeJ9kYq5t5S2vciUdFPXv/ikFTb0zK8q9vXkg4+WAJuYXGiVT1H28AkD2C+IkXVw==" + }, + "node_modules/@types/request": { + "version": "2.48.1", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz", + "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==", + "dependencies": { + "@types/caseless": "*", + "@types/form-data": "*", + "@types/node": "*", + "@types/tough-cookie": "*" } }, - "@types/tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha512-vOVmaruQG5EatOU/jM6yU2uCp3Lz6mK1P5Ztu4iJjfM4SVHU9XYktPUQtKlIXuahqXHdEyUarMrBEwg5Cwu+bA==" + "node_modules/@types/tough-cookie": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", + "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" }, - "abbrev": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz", - "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=" + "node_modules/abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" }, - "accepts": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", - "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", - "requires": { - "mime-types": "2.1.17", + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/accepts": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "dependencies": { + "mime-types": "~2.1.18", "negotiator": "0.6.1" + }, + "engines": { + "node": ">= 0.6" } }, - "acorn": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz", - "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==" + "node_modules/acorn": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } }, - "acorn-jsx": { + "node_modules/acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "dependencies": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "requires": { - "acorn": "3.3.0" - }, "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" - } + "acorn": "^3.0.4" } }, - "addressparser": { + "node_modules/acorn-jsx/node_modules/acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/addressparser": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=" }, - "ajv": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.2.tgz", - "integrity": "sha1-R8aNaehvXZUxA7AHSpQw3GPaXjk=", - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "json-schema-traverse": "0.3.1", - "json-stable-stringify": "1.0.1" + "node_modules/after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, + "node_modules/agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "engines": { + "node": ">= 6.0.0" } }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=" + "node_modules/agentkeepalive": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz", + "integrity": "sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8=", + "engines": { + "node": ">= 0.10.0" + } }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "node_modules/ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dependencies": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + "node_modules/ajv-keywords": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==" }, - "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", - "requires": { - "string-width": "2.1.1" + "node_modules/algoliasearch": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.35.1.tgz", + "integrity": "sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ==", + "dependencies": { + "agentkeepalive": "^2.2.0", + "debug": "^2.6.9", + "envify": "^4.0.0", + "es6-promise": "^4.1.0", + "events": "^1.1.0", + "foreach": "^2.0.5", + "global": "^4.3.2", + "inherits": "^2.0.1", + "isarray": "^2.0.1", + "load-script": "^1.0.0", + "object-keys": "^1.0.11", + "querystring-es3": "^0.2.1", + "reduce": "^1.0.1", + "semver": "^5.1.0", + "tunnel-agent": "^0.6.0" }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/algoliasearch/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "3.0.0" - } - } + "ms": "2.0.0" } }, - "ansi-escapes": { + "node_modules/algoliasearch/node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "node_modules/algoliasearch/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "node_modules/algoliasearch/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dependencies": { + "string-width": "^3.0.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "dependencies": { + "ansi-wrap": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-escapes": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "engines": { + "node": ">=0.10.0" + } }, - "ansi-regex": { + "node_modules/ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } }, - "any-observable": { + "node_modules/ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/any-observable": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.2.0.tgz", "integrity": "sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "anymatch": { + "node_modules/anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" + "dependencies": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" } }, - "app-root-path": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz", - "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=", - "dev": true + "node_modules/app-root-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.1.0.tgz", + "integrity": "sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo=", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } }, - "append-field": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz", - "integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo=" + "node_modules/append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dependencies": { + "buffer-equal": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "append-transform": { + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, + "node_modules/append-transform": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", - "requires": { - "default-require-extensions": "1.0.0" + "dependencies": { + "default-require-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "archy": { + "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "requires": { - "sprintf-js": "1.0.3" + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "arr-diff": { + "node_modules/arr-diff": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "requires": { - "arr-flatten": "1.1.0" + "dependencies": { + "arr-flatten": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "arr-flatten": { + "node_modules/arr-filter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", + "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "dependencies": { + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "engines": { + "node": ">=0.10.0" + } }, - "array-differ": { + "node_modules/arr-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", + "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "dependencies": { + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-differ": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "engines": { + "node": ">=0.10.0" + } }, - "array-each": { + "node_modules/array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "engines": { + "node": ">=0.10.0" + } }, - "array-flatten": { + "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "array-slice": { + "node_modules/array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, + "node_modules/array-initial": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", + "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "dependencies": { + "array-slice": "^1.0.0", + "is-number": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-initial/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-last": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", + "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dependencies": { + "is-number": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-last/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-sort": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.0.0.tgz", - "integrity": "sha1-5zA08A3MH0CHYAj9IP6ud71LfC8=" + "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", + "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dependencies": { + "default-compare": "^1.0.0", + "get-value": "^2.0.6", + "kind-of": "^5.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "array-union": { + "node_modules/array-sort/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "1.0.3" + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "array-uniq": { + "node_modules/array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "engines": { + "node": ">=0.10.0" + } }, - "array-unique": { + "node_modules/array-unique": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "engines": { + "node": ">=0.10.0" + } }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "node_modules/arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dependencies": { + "safer-buffer": "~2.1.0" + } }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } }, - "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=" + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "engines": { + "node": "*" + } }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "engines": { + "node": ">=0.10.0" + } }, - "async-each": { + "node_modules/async": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.1.1.tgz", + "integrity": "sha512-X5Dj8hK1pJNC2Wzo2Rcp9FBVdJMGRR/S7V+lH46s8GVFhtbo5O4Le5GECCF/8PISVdkUA6mMPvgz7qTTD1rf1g==" + }, + "node_modules/async-done": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", + "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.2", + "process-nextick-args": "^2.0.0", + "stream-exhaust": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/async-done/node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/async-each": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.2.tgz", + "integrity": "sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg==" + }, + "node_modules/async-limiter": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, - "async.ensureasync": { + "node_modules/async-settle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", + "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "dependencies": { + "async-done": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/async.ensureasync": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.ensureasync/-/async.ensureasync-0.5.2.tgz", "integrity": "sha1-w8fkpOmzHZaHXVa4UEWYRG4eMF0=", - "requires": { + "dependencies": { "async.util.ensureasync": "0.5.2" } }, - "async.queue": { + "node_modules/async.queue": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.queue/-/async.queue-0.5.2.tgz", "integrity": "sha1-jV2QgS4UgQZrwJBOjMFxKxfDvXw=", - "requires": { + "dependencies": { "async.util.queue": "0.5.2" } }, - "async.util.arrayeach": { + "node_modules/async.util.arrayeach": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz", "integrity": "sha1-WMTpgCjVXWm/sFrrOvROClVagpw=" }, - "async.util.ensureasync": { + "node_modules/async.util.ensureasync": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.ensureasync/-/async.util.ensureasync-0.5.2.tgz", "integrity": "sha1-EJB/LL0GegYfma5tIuCM7TDbDWg=", - "requires": { + "dependencies": { "async.util.restparam": "0.5.2", "async.util.setimmediate": "0.5.2" } }, - "async.util.isarray": { + "node_modules/async.util.isarray": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz", "integrity": "sha1-5i2sjyY29lh13PdSHC0k0N+yu98=" }, - "async.util.map": { + "node_modules/async.util.map": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.map/-/async.util.map-0.5.2.tgz", "integrity": "sha1-5YjvhuCzq18CfZevTWg10FXKadY=" }, - "async.util.noop": { + "node_modules/async.util.noop": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz", "integrity": "sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk=" }, - "async.util.onlyonce": { + "node_modules/async.util.onlyonce": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz", "integrity": "sha1-uOb8AErckjFk154y8oE+5GXCT/I=" }, - "async.util.queue": { + "node_modules/async.util.queue": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.queue/-/async.util.queue-0.5.2.tgz", "integrity": "sha1-V/Zavho83yc9MavSirlUJfgiLuU=", - "requires": { + "dependencies": { "async.util.arrayeach": "0.5.2", "async.util.isarray": "0.5.2", "async.util.map": "0.5.2", @@ -597,1268 +1044,1824 @@ "async.util.setimmediate": "0.5.2" } }, - "async.util.restparam": { + "node_modules/async.util.restparam": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz", "integrity": "sha1-A+/r88Ane5ciDlJaunUPXgT8gM0=" }, - "async.util.setimmediate": { + "node_modules/async.util.setimmediate": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz", "integrity": "sha1-KBLrq/KlgCd1jUvHeT0cz68QJV8=" }, - "asynckit": { + "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, - "atob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", - "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=" + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } }, - "aws-sdk": { - "version": "2.205.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.205.0.tgz", - "integrity": "sha1-GpNzAlPivgJ6S9OvkkjL2gVz3oA=", - "requires": { + "node_modules/aws-sdk": { + "version": "2.425.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.425.0.tgz", + "integrity": "sha512-SM2qZJPlZUKVzSSqNuCvONOhJ2kcFvU+hAwutjQeje2VKpSAbUbFCFWl6cki2FjiyGZYEPfl0Q+3ANJO8gx9BA==", + "dependencies": { "buffer": "4.9.1", "events": "1.1.1", + "ieee754": "1.1.8", "jmespath": "0.15.0", "querystring": "0.2.0", "sax": "1.2.1", "url": "0.10.3", - "uuid": "3.1.0", - "xml2js": "0.4.17", - "xmlbuilder": "4.2.1" + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "engines": { + "node": ">= 0.8.0" } }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "engines": { + "node": "*" + } }, - "axios": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.17.1.tgz", - "integrity": "sha1-LY4+XQvb1zJ/kbyBT1xXZg+Bgk0=", - "requires": { - "follow-redirects": "1.4.1", - "is-buffer": "1.1.5" + "node_modules/aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "node_modules/axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "deprecated": "Critical security vulnerability fixed in v0.21.1. For more information, see https://github.com/axios/axios/pull/3410", + "dependencies": { + "follow-redirects": "1.5.10" } }, - "babel-cli": { + "node_modules/babel-cli": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", - "requires": { - "babel-core": "6.26.0", - "babel-polyfill": "6.26.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "chokidar": "1.7.0", - "commander": "2.11.0", - "convert-source-map": "1.5.0", - "fs-readdir-recursive": "1.0.0", - "glob": "7.1.2", - "lodash": "4.17.4", - "output-file-sync": "1.1.2", - "path-is-absolute": "1.0.1", - "slash": "1.0.0", - "source-map": "0.5.7", - "v8flags": "2.1.1" + "dependencies": { + "babel-core": "^6.26.0", + "babel-polyfill": "^6.26.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "chokidar": "^1.6.1", + "commander": "^2.11.0", + "convert-source-map": "^1.5.0", + "fs-readdir-recursive": "^1.0.0", + "glob": "^7.1.2", + "lodash": "^4.17.4", + "output-file-sync": "^1.1.2", + "path-is-absolute": "^1.0.1", + "slash": "^1.0.0", + "source-map": "^0.5.6", + "v8flags": "^2.1.1" + }, + "bin": { + "babel": "bin/babel.js", + "babel-doctor": "bin/babel-doctor.js", + "babel-external-helpers": "bin/babel-external-helpers.js", + "babel-node": "bin/babel-node.js" } }, - "babel-code-frame": { + "node_modules/babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, - "babel-core": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", - "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", - "requires": { - "babel-code-frame": "6.26.0", - "babel-generator": "6.26.0", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "convert-source-map": "1.5.0", - "debug": "2.6.8", - "json5": "0.5.1", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.7", - "slash": "1.0.0", - "source-map": "0.5.7" - }, - "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - } + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" } }, - "babel-generator": { + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/babel-core": { "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz", - "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=", - "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.4", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "dependencies": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" + } + }, + "node_modules/babel-core/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" } }, - "babel-helper-bindify-decorators": { + "node_modules/babel-core/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dependencies": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "node_modules/babel-helper-bindify-decorators": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", - "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-helper-builder-binary-assignment-operator-visitor": { + "node_modules/babel-helper-builder-binary-assignment-operator-visitor": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "requires": { - "babel-helper-explode-assignable-expression": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-helper-call-delegate": { + "node_modules/babel-helper-call-delegate": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-helper-define-map": { + "node_modules/babel-helper-define-map": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, - "babel-helper-explode-assignable-expression": { + "node_modules/babel-helper-explode-assignable-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-helper-explode-class": { + "node_modules/babel-helper-explode-class": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", - "requires": { - "babel-helper-bindify-decorators": "6.24.1", - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-helper-function-name": { + "node_modules/babel-helper-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-helper-get-function-arity": { + "node_modules/babel-helper-get-function-arity": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-helper-hoist-variables": { + "node_modules/babel-helper-hoist-variables": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-helper-optimise-call-expression": { + "node_modules/babel-helper-optimise-call-expression": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-helper-regex": { + "node_modules/babel-helper-regex": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, - "babel-helper-remap-async-to-generator": { + "node_modules/babel-helper-remap-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-helper-replace-supers": { + "node_modules/babel-helper-replace-supers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "requires": { - "babel-helper-optimise-call-expression": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-helpers": { + "node_modules/babel-helpers": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "babel-messages": { + "node_modules/babel-messages": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-add-module-exports": { + "node_modules/babel-plugin-add-module-exports": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=" }, - "babel-plugin-check-es2015-constants": { + "node_modules/babel-plugin-check-es2015-constants": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-syntax-async-functions": { + "node_modules/babel-plugin-syntax-async-functions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" }, - "babel-plugin-syntax-async-generators": { + "node_modules/babel-plugin-syntax-async-generators": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=" }, - "babel-plugin-syntax-class-properties": { + "node_modules/babel-plugin-syntax-class-properties": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=" }, - "babel-plugin-syntax-decorators": { + "node_modules/babel-plugin-syntax-decorators": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=" }, - "babel-plugin-syntax-dynamic-import": { + "node_modules/babel-plugin-syntax-dynamic-import": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=" }, - "babel-plugin-syntax-exponentiation-operator": { + "node_modules/babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" }, - "babel-plugin-syntax-object-rest-spread": { + "node_modules/babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" }, - "babel-plugin-syntax-trailing-function-commas": { + "node_modules/babel-plugin-syntax-trailing-function-commas": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" }, - "babel-plugin-transform-async-generator-functions": { + "node_modules/babel-plugin-transform-async-generator-functions": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", - "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-generators": "6.13.0", - "babel-runtime": "6.26.0" + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-async-to-generator": { + "node_modules/babel-plugin-transform-async-to-generator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-functions": "6.13.0", - "babel-runtime": "6.26.0" + "dependencies": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-class-properties": { + "node_modules/babel-plugin-transform-class-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-plugin-syntax-class-properties": "6.13.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "babel-plugin-transform-decorators": { + "node_modules/babel-plugin-transform-decorators": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", - "requires": { - "babel-helper-explode-class": "6.24.1", - "babel-plugin-syntax-decorators": "6.13.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-plugin-transform-es2015-arrow-functions": { + "node_modules/babel-plugin-transform-es2015-arrow-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-block-scoped-functions": { + "node_modules/babel-plugin-transform-es2015-block-scoped-functions": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-block-scoping": { + "node_modules/babel-plugin-transform-es2015-block-scoping": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "lodash": "4.17.4" + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" } }, - "babel-plugin-transform-es2015-classes": { + "node_modules/babel-plugin-transform-es2015-classes": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "requires": { - "babel-helper-define-map": "6.26.0", - "babel-helper-function-name": "6.24.1", - "babel-helper-optimise-call-expression": "6.24.1", - "babel-helper-replace-supers": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" - } - }, - "babel-plugin-transform-es2015-computed-properties": { + "dependencies": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "node_modules/babel-plugin-transform-es2015-computed-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "requires": { - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "babel-plugin-transform-es2015-destructuring": { + "node_modules/babel-plugin-transform-es2015-destructuring": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-duplicate-keys": { + "node_modules/babel-plugin-transform-es2015-duplicate-keys": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-plugin-transform-es2015-for-of": { + "node_modules/babel-plugin-transform-es2015-for-of": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-function-name": { + "node_modules/babel-plugin-transform-es2015-function-name": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-plugin-transform-es2015-literals": { + "node_modules/babel-plugin-transform-es2015-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-modules-amd": { + "node_modules/babel-plugin-transform-es2015-modules-amd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz", - "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=", - "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-types": "6.26.0" + "node_modules/babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dependencies": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" } }, - "babel-plugin-transform-es2015-modules-systemjs": { + "node_modules/babel-plugin-transform-es2015-modules-systemjs": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "babel-plugin-transform-es2015-modules-umd": { + "node_modules/babel-plugin-transform-es2015-modules-umd": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0" + "dependencies": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" } }, - "babel-plugin-transform-es2015-object-super": { + "node_modules/babel-plugin-transform-es2015-object-super": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.26.0" + "dependencies": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-parameters": { + "node_modules/babel-plugin-transform-es2015-parameters": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "requires": { - "babel-helper-call-delegate": "6.24.1", - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" } }, - "babel-plugin-transform-es2015-shorthand-properties": { + "node_modules/babel-plugin-transform-es2015-shorthand-properties": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-plugin-transform-es2015-spread": { + "node_modules/babel-plugin-transform-es2015-spread": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-sticky-regex": { + "node_modules/babel-plugin-transform-es2015-sticky-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-plugin-transform-es2015-template-literals": { + "node_modules/babel-plugin-transform-es2015-template-literals": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-typeof-symbol": { + "node_modules/babel-plugin-transform-es2015-typeof-symbol": { "version": "6.23.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "requires": { - "babel-runtime": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-es2015-unicode-regex": { + "node_modules/babel-plugin-transform-es2015-unicode-regex": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "requires": { - "babel-helper-regex": "6.26.0", - "babel-runtime": "6.26.0", - "regexpu-core": "2.0.0" + "dependencies": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" } }, - "babel-plugin-transform-exponentiation-operator": { + "node_modules/babel-plugin-transform-exponentiation-operator": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", - "babel-plugin-syntax-exponentiation-operator": "6.13.0", - "babel-runtime": "6.26.0" + "dependencies": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" } }, - "babel-plugin-transform-object-rest-spread": { + "node_modules/babel-plugin-transform-object-rest-spread": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", - "requires": { - "babel-plugin-syntax-object-rest-spread": "6.13.0", - "babel-runtime": "6.26.0" + "dependencies": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" } }, - "babel-plugin-transform-regenerator": { + "node_modules/babel-plugin-transform-regenerator": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "requires": { - "regenerator-transform": "0.10.1" + "dependencies": { + "regenerator-transform": "^0.10.0" } }, - "babel-plugin-transform-strict-mode": { + "node_modules/babel-plugin-transform-strict-mode": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0" + "dependencies": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" } }, - "babel-polyfill": { + "node_modules/babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "requires": { - "babel-runtime": "6.26.0", - "core-js": "2.5.1", - "regenerator-runtime": "0.10.5" - }, "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" - } + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" } }, - "babel-preset-es2015": { + "node_modules/babel-polyfill/node_modules/regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + }, + "node_modules/babel-preset-es2015": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", - "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.26.0", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.26.0", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-regenerator": "6.26.0" - } - }, - "babel-preset-stage-2": { + "dependencies": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" + } + }, + "node_modules/babel-preset-stage-2": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", - "requires": { - "babel-plugin-syntax-dynamic-import": "6.18.0", - "babel-plugin-transform-class-properties": "6.24.1", - "babel-plugin-transform-decorators": "6.24.1", - "babel-preset-stage-3": "6.24.1" + "dependencies": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" } }, - "babel-preset-stage-3": { + "node_modules/babel-preset-stage-3": { "version": "6.24.1", "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", - "requires": { - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-generator-functions": "6.24.1", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-object-rest-spread": "6.26.0" + "dependencies": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" } }, - "babel-register": { + "node_modules/babel-register": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "requires": { - "babel-core": "6.26.0", - "babel-runtime": "6.26.0", - "core-js": "2.5.1", - "home-or-tmp": "2.0.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "source-map-support": "0.4.17" + "dependencies": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" } }, - "babel-runtime": { + "node_modules/babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "2.5.1", - "regenerator-runtime": "0.11.0" + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" } }, - "babel-template": { + "node_modules/babel-template": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.4" + "dependencies": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" } }, - "babel-traverse": { + "node_modules/babel-traverse": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.8", - "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" - }, "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - } + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "node_modules/babel-traverse/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" } }, - "babel-types": { + "node_modules/babel-traverse/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/babel-types": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" + "dependencies": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" } }, - "babylon": { + "node_modules/babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "bin": { + "babylon": "bin/babylon.js" + } }, - "balanced-match": { + "node_modules/bach": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", + "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "dependencies": { + "arr-filter": "^1.1.1", + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "array-each": "^1.0.0", + "array-initial": "^1.0.0", + "array-last": "^1.1.1", + "async-done": "^1.2.2", + "async-settle": "^1.0.0", + "now-and-later": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, - "base64-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", - "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==" + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "base64url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-2.0.0.tgz", - "integrity": "sha1-6sFuA+oUOO/5Qj1puqNiYu0fcLs=" + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "basic-auth": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-1.1.0.tgz", - "integrity": "sha1-RSIe5Cn37h5QNb4/UVM/HN/SmIQ=" + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "bcrypt-nodejs": { + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/bcrypt-nodejs": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz", "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs=" }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "optional": true, - "requires": { - "tweetnacl": "0.14.5" + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dependencies": { + "tweetnacl": "^0.14.3" } }, - "beeper": { + "node_modules/beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "engines": { + "node": ">=0.10.0" + } }, - "binary-extensions": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", - "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=" + "node_modules/better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "dependencies": { + "callsite": "1.0.0" + }, + "engines": { + "node": "*" + } }, - "bluebird": { + "node_modules/binary-extensions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", + "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, + "node_modules/bluebird": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" }, - "body-parser": { + "node_modules/body-parser": { "version": "1.17.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", - "requires": { + "dependencies": { "bytes": "2.4.0", - "content-type": "1.0.2", + "content-type": "~1.0.2", "debug": "2.6.7", - "depd": "1.1.1", - "http-errors": "1.6.2", + "depd": "~1.1.0", + "http-errors": "~1.6.1", "iconv-lite": "0.4.15", - "on-finished": "2.3.0", + "on-finished": "~2.3.0", "qs": "6.4.0", - "raw-body": "2.2.0", - "type-is": "1.6.15" + "raw-body": "~2.2.0", + "type-is": "~1.6.15" }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", + "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } - } + "ms": "2.0.0" } }, - "boom": { + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/boom": { "version": "2.10.1", "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "requires": { - "hoek": "2.16.3" + "dependencies": { + "hoek": "2.x.x" + }, + "engines": { + "node": ">=0.10.40" } }, - "bottleneck": { + "node_modules/bottleneck": { "version": "1.16.0", "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-1.16.0.tgz", "integrity": "sha1-1s4TgIUnr8gLaQkvFWBmVeWyHxo=" }, - "boxen": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.1.tgz", - "integrity": "sha1-DxHn/jRO25OXl3/BPt5/ZNlWSB0=", - "requires": { - "ansi-align": "2.0.0", - "camelcase": "4.1.0", - "chalk": "2.1.0", - "cli-boxes": "1.0.0", - "string-width": "2.1.1", - "term-size": "1.2.0", - "widest-line": "1.0.0" + "node_modules/bowser": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.6.1.tgz", + "integrity": "sha512-hySGUuLhi0KetfxPZpuJOsjM0kRvCiCgPBygBkzGzJNsq/nbJmaO8QJc6xlWfeFFnMvtd/LeKkhDJGVrmVobUA==" + }, + "node_modules/boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "requires": { - "color-convert": "1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "3.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "requires": { - "has-flag": "2.0.0" - } - } + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "1.0.0", + "node_modules/boxen/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/boxen/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/boxen/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/boxen/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/boxen/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { + "node_modules/braces": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" + "dependencies": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "browser-stdout": { + "node_modules/browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" + }, + "node_modules/browser-stdout": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" }, - "bson": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz", - "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw=" + "node_modules/bson": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==", + "engines": { + "node": ">=0.6.19" + } }, - "buffer": { + "node_modules/buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.8", - "isarray": "1.0.0" + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, - "buffer-equal-constant-time": { + "node_modules/buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, - "buffer-shims": { + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "node_modules/buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" }, - "builtin-modules": { + "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "engines": { + "node": ">=0.10.0" + } }, - "busboy": { + "node_modules/busboy": { "version": "0.2.14", "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", - "requires": { + "dependencies": { "dicer": "0.2.5", - "readable-stream": "1.1.14" + "readable-stream": "1.1.x" }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/busboy/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/busboy/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, - "bytes": { + "node_modules/busboy/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/bytes": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" }, - "cachedir": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.1.1.tgz", - "integrity": "sha1-4TYwdeogahJ2fZK7cRyKL3ahD2I=", - "requires": { - "os-homedir": "1.0.2" + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + "node_modules/cache-base/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "requires": { - "callsites": "0.2.0" + "node_modules/cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "engines": { + "node": ">=8" } }, - "callsites": { + "node_modules/cacheable-request/node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dependencies": { + "os-homedir": "^1.0.1" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + }, + "node_modules/caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dependencies": { + "callsites": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "engines": { + "node": ">=0.10.0" + } }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + "node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "engines": { + "node": ">=0.10.0" + } }, - "camelize": { + "node_modules/camelize": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, - "capture-stack-trace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "optional": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" - } + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, - "chai": { + "node_modules/chai": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", - "requires": { - "assertion-error": "1.0.2", - "check-error": "1.0.2", - "deep-eql": "3.0.1", - "get-func-name": "2.0.0", - "pathval": "1.1.0", - "type-detect": "4.0.3" + "dependencies": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=4" } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "check-error": { + "node_modules/chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + }, + "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "engines": { + "node": "*" + } }, - "chokidar": { + "node_modules/chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" + "dependencies": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "optionalDependencies": { + "fsevents": "^1.0.0" } }, - "ci-info": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz", - "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==", + "node_modules/ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", "dev": true }, - "circular-json": { + "node_modules/circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "cli-cursor": { + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "requires": { - "restore-cursor": "1.0.1" + "dependencies": { + "restore-cursor": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "cli-spinners": { + "node_modules/cli-spinners": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "cli-truncate": { + "node_modules/cli-truncate": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", "dev": true, - "requires": { + "dependencies": { "slice-ansi": "0.0.4", - "string-width": "1.0.2" + "string-width": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "cli-width": { + "node_modules/cli-truncate/node_modules/slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "optional": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - }, + "node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "optional": true - } + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" } }, - "clone": { + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/clone-response": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=" + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dependencies": { + "mimic-response": "^1.0.0" + } }, - "clone-stats": { + "node_modules/clone-stats": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" }, - "co": { + "node_modules/cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } }, - "code-point-at": { + "node_modules/code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "engines": { + "node": ">=0.10.0" + } }, - "color-convert": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", - "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", - "requires": { + "node_modules/collection-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", + "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "dependencies": { + "arr-map": "^2.0.2", + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collection-map/node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { "color-name": "1.1.3" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "bin": { + "color-support": "bin.js" + } }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "requires": { - "delayed-stream": "1.0.0" + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" } }, - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + "node_modules/combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } }, - "commitizen": { + "node_modules/commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + }, + "node_modules/commitizen": { "version": "2.9.6", "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-2.9.6.tgz", "integrity": "sha1-wNAFNe8mTaf2Nzft/aQiiYP6IpE=", - "requires": { - "cachedir": "1.1.1", + "dependencies": { + "cachedir": "^1.1.0", "chalk": "1.1.3", "cz-conventional-changelog": "1.2.0", "dedent": "0.6.0", "detect-indent": "4.0.0", "find-node-modules": "1.0.4", "find-root": "1.0.0", - "fs-extra": "1.0.0", + "fs-extra": "^1.0.0", "glob": "7.1.1", "inquirer": "1.2.3", "lodash": "4.17.2", @@ -1867,2134 +2870,20851 @@ "shelljs": "0.7.6", "strip-json-comments": "2.0.1" }, + "bin": { + "commitizen": "bin/commitizen", + "git-cz": "bin/git-cz" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/commitizen/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/commitizen/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dependencies": { - "cz-conventional-changelog": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-1.2.0.tgz", - "integrity": "sha1-K8oElkyJGbI/P9aonvXmAIsxs/g=", - "requires": { - "conventional-commit-types": "2.2.0", - "lodash.map": "4.6.0", - "longest": "1.0.1", - "pad-right": "0.2.2", - "right-pad": "1.0.1", - "word-wrap": "1.2.3" - } - }, - "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "lodash": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.2.tgz", - "integrity": "sha1-NKMFW6vgTOQkZ7YH1wAHLH/2v0I=" - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "component-emitter": { + "node_modules/commitizen/node_modules/cz-conventional-changelog": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-1.2.0.tgz", + "integrity": "sha1-K8oElkyJGbI/P9aonvXmAIsxs/g=", + "dependencies": { + "conventional-commit-types": "^2.0.0", + "lodash.map": "^4.5.1", + "longest": "^1.0.1", + "pad-right": "^0.2.2", + "right-pad": "^1.0.1", + "word-wrap": "^1.0.3" + } + }, + "node_modules/commitizen/node_modules/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/commitizen/node_modules/lodash": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.2.tgz", + "integrity": "sha1-NKMFW6vgTOQkZ7YH1wAHLH/2v0I=" + }, + "node_modules/commitizen/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, + "node_modules/component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, - "compressible": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.11.tgz", - "integrity": "sha1-FnGKdd4oPtjmBAQWJaIGRYZ5fYo=", - "requires": { - "mime-db": "1.30.0" + "node_modules/component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, + "node_modules/compressible": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz", + "integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==", + "dependencies": { + "mime-db": ">= 1.38.0 < 2" + }, + "engines": { + "node": ">= 0.6" } }, - "compression": { + "node_modules/compression": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.0.tgz", "integrity": "sha1-AwyfGY8WQ6BX13anOOki2kNzAS0=", - "requires": { - "accepts": "1.3.4", + "dependencies": { + "accepts": "~1.3.3", "bytes": "2.5.0", - "compressible": "2.0.11", + "compressible": "~2.0.10", "debug": "2.6.8", - "on-headers": "1.0.1", + "on-headers": "~1.0.1", "safe-buffer": "5.1.1", - "vary": "1.1.1" + "vary": "~1.1.1" }, - "dependencies": { - "bytes": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz", - "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=" - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - } + "engines": { + "node": ">= 0.8.0" } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "node_modules/compression/node_modules/bytes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz", + "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=", + "engines": { + "node": ">= 0.6" + } }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" + "node_modules/compression/node_modules/debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dependencies": { + "ms": "2.0.0" } }, - "configstore": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz", - "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==", - "requires": { - "dot-prop": "4.2.0", - "graceful-fs": "4.1.11", - "make-dir": "1.0.0", - "unique-string": "1.0.0", - "write-file-atomic": "2.3.0", - "xdg-basedir": "3.0.0" + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/compression/node_modules/safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, - "connect": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.2.tgz", - "integrity": "sha1-aU6NIGgb/kkCgsiriGvpjwn0L+c=", - "requires": { - "debug": "2.6.7", - "finalhandler": "1.0.3", - "parseurl": "1.3.1", - "utils-merge": "1.0.0" - }, + "node_modules/configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", "dependencies": { - "debug": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", - "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", - "requires": { - "ms": "2.0.0" - } - }, - "finalhandler": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.3.tgz", - "integrity": "sha1-70fneVDpmXgOhgIqVg4yF+DQzIk=", - "requires": { - "debug": "2.6.7", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.1", - "statuses": "1.3.1", - "unpipe": "1.0.0" - } - } + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "contains-path": { + "node_modules/contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "engines": { + "node": ">=0.10.0" + } }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } }, - "content-security-policy-builder": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-1.1.0.tgz", - "integrity": "sha1-2R8bB2I2wRmFDH3umSS/VeBXcrM=", - "requires": { - "dashify": "0.2.2" + "node_modules/content-security-policy-builder": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz", + "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==", + "engines": { + "node": ">=4.0.0" } }, - "content-type": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.2.tgz", - "integrity": "sha1-t9ETrueo3Se9IRM8TcJSnfFyHu0=" + "node_modules/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==", + "engines": { + "node": ">= 0.6" + } }, - "conventional-commit-types": { + "node_modules/conventional-commit-types": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-2.2.0.tgz", "integrity": "sha1-XblXOdbCEqy+e29lahG5QLqmiUY=" }, - "convert-source-map": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", - "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=" + "node_modules/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==", + "dependencies": { + "safe-buffer": "~5.1.1" + } }, - "cookie": { + "node_modules/cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "engines": { + "node": ">= 0.6" + } }, - "cookie-parser": { + "node_modules/cookie-parser": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", - "requires": { + "dependencies": { "cookie": "0.3.1", "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" } }, - "cookie-signature": { + "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, - "cookiejar": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz", - "integrity": "sha1-Qa1XsbVVlR7BcUEqgZQrHoIA00o=" + "node_modules/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" }, - "core-js": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", - "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "engines": { + "node": ">=0.10.0" + } }, - "core-util-is": { + "node_modules/copy-props": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", + "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", + "dependencies": { + "each-props": "^1.3.0", + "is-plain-object": "^2.0.1" + } + }, + "node_modules/core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" + }, + "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, - "cors": { + "node_modules/cors": { "version": "2.8.4", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", - "requires": { - "object-assign": "4.1.1", - "vary": "1.1.1" + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">=0.10.0" } }, - "cosmiconfig": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-3.1.0.tgz", - "integrity": "sha512-zedsBhLSbPBms+kE7AH4vHg6JsKDz6epSv2/+5XHs8ILHlgDciSJfSWf8sX9aQ52Jb7KI7VswUTsLpR/G0cr2Q==", + "node_modules/cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", "dev": true, - "requires": { - "is-directory": "0.3.1", - "js-yaml": "3.10.0", - "parse-json": "3.0.0", - "require-from-string": "2.0.1" + "dependencies": { + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0", + "require-from-string": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cosmiconfig/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cosmiconfig/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, "dependencies": { - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "parse-json": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-3.0.0.tgz", - "integrity": "sha1-+m9HsY4jgm6tMvJj50TQ4ehH+xM=", - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - } + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "coveralls": { + "node_modules/cosmiconfig/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/coveralls": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.1.tgz", "integrity": "sha1-1wu5rMGDXsTwY/+drFQjwXsR8Xg=", - "requires": { + "dependencies": { "js-yaml": "3.6.1", "lcov-parse": "0.0.10", "log-driver": "1.2.5", "minimist": "1.2.0", "request": "2.79.0" }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } + "bin": { + "coveralls": "bin/coveralls.js" + }, + "engines": { + "node": ">=0.8.6" } }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "requires": { - "capture-stack-trace": "1.0.0" + "node_modules/coveralls/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" } }, - "cross-env": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.0.5.tgz", - "integrity": "sha1-Q4PTZNlmCHPdGFs5ivO/717//vM=", - "requires": { - "cross-spawn": "5.1.0", - "is-windows": "1.0.1" - }, - "dependencies": { - "is-windows": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz", - "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=" - } + "node_modules/coveralls/node_modules/assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "engines": { + "node": ">=0.8" } }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.3.0" + "node_modules/coveralls/node_modules/aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "engines": { + "node": "*" } }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "requires": { - "boom": "2.10.1" + "node_modules/coveralls/node_modules/caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "node_modules/coveralls/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + "node_modules/coveralls/node_modules/form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } }, - "css": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz", - "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", - "requires": { - "inherits": "2.0.3", - "source-map": "0.1.43", - "source-map-resolve": "0.3.1", - "urix": "0.1.0" + "node_modules/coveralls/node_modules/har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "dependencies": { + "chalk": "^1.1.1", + "commander": "^2.9.0", + "is-my-json-valid": "^2.12.4", + "pinkie-promise": "^2.0.0" + }, + "bin": { + "har-validator": "bin/har-validator" }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/coveralls/node_modules/http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", "dependencies": { - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "requires": { - "amdefine": "1.0.1" - } - } + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "cycle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" + "node_modules/coveralls/node_modules/js-yaml": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", + "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^2.6.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } }, - "cz-conventional-changelog": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.0.0.tgz", - "integrity": "sha1-Val5r9/pXnAkh50qD1kkYwFwtTM=", - "requires": { - "conventional-commit-types": "2.2.0", - "lodash.map": "4.6.0", - "longest": "1.0.1", - "pad-right": "0.2.2", - "right-pad": "1.0.1", - "word-wrap": "1.2.3" + "node_modules/coveralls/node_modules/oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "engines": { + "node": "*" } }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "requires": { - "es5-ext": "0.10.30" + "node_modules/coveralls/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "node_modules/coveralls/node_modules/qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "engines": { + "node": ">=0.6" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "1.0.0" - }, + "node_modules/coveralls/node_modules/request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.11.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~2.0.6", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "qs": "~6.3.0", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "~0.4.1", + "uuid": "^3.0.0" + }, + "engines": { + "node": ">= 4" } }, - "dasherize": { + "node_modules/coveralls/node_modules/supports-color": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", - "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" - }, - "dashify": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dashify/-/dashify-0.2.2.tgz", - "integrity": "sha1-agdBWgHJH69KMuONnfunH2HLIP4=" - }, - "date-fns": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz", - "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==", - "dev": true + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } }, - "dateformat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", - "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=" + "node_modules/coveralls/node_modules/tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dependencies": { + "punycode": "^1.4.1" + }, + "engines": { + "node": ">=0.8" + } }, - "debug": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.0.1.tgz", - "integrity": "sha512-6nVc6S36qbt/mutyt+UGMnawAMrPDZUPQjRZI3FS9tCtDRhvxJbK79unYBLPi+z5SLXQ3ftoVBFCblQtNSls8w==", - "requires": { - "ms": "2.0.0" + "node_modules/coveralls/node_modules/tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "engines": { + "node": "*" } }, - "debug-fabulous": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.1.1.tgz", - "integrity": "sha512-UhD+fzBYnlHjOpUrSeKT+sbZAqxDsqoXAsESKQPAoBm2j/0F9l9IeOEYDST8Lkz1L2zA9KvIxp58h923wCWjDQ==", - "requires": { - "debug": "2.3.0", - "memoizee": "0.4.9", - "object-assign": "4.1.0" + "node_modules/cron": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz", + "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==", + "dependencies": { + "moment-timezone": "^0.5.x" + } + }, + "node_modules/cross-env": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.0.5.tgz", + "integrity": "sha1-Q4PTZNlmCHPdGFs5ivO/717//vM=", + "dependencies": { + "cross-spawn": "^5.1.0", + "is-windows": "^1.0.0" + }, + "bin": { + "cross-env": "dist/bin/cross-env.js", + "cross-env-shell": "dist/bin/cross-env-shell.js" }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/cross-fetch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz", + "integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==", "dependencies": { - "debug": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.0.tgz", - "integrity": "sha1-ORLcVdcWf8OvF9K4XBP5PertqkM=", - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=" - }, - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=" - } + "node-fetch": "2.6.1" } }, - "decamelize": { + "node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "dependencies": { + "boom": "2.x.x" + }, + "engines": { + "node": ">=0.10.40" + } + }, + "node_modules/crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "node_modules/cssstyle": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz", + "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==", + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + }, + "node_modules/cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/cz-conventional-changelog": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.0.0.tgz", + "integrity": "sha1-Val5r9/pXnAkh50qD1kkYwFwtTM=", + "dependencies": { + "conventional-commit-types": "^2.0.0", + "lodash.map": "^4.5.1", + "longest": "^1.0.1", + "pad-right": "^0.2.2", + "right-pad": "^1.0.1", + "word-wrap": "^1.0.3" + } + }, + "node_modules/d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "dependencies": { + "es5-ext": "^0.10.9" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dasherize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", + "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "node_modules/dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.0.1.tgz", + "integrity": "sha512-6nVc6S36qbt/mutyt+UGMnawAMrPDZUPQjRZI3FS9tCtDRhvxJbK79unYBLPi+z5SLXQ3ftoVBFCblQtNSls8w==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/debug-fabulous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", + "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", + "dependencies": { + "debug": "3.X", + "memoizee": "0.4.X", + "object-assign": "4.X" + } + }, + "node_modules/debug-fabulous/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "optional": true + "engines": { + "node": ">=0.10.0" + } }, - "dedent": { + "node_modules/decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==" + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/dedent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz", "integrity": "sha1-Dm2o8M5Sg471zsXI+TlrDBtko8s=" }, - "deep-eql": { + "node_modules/deep-eql": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "requires": { - "type-detect": "4.0.3" + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" } }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } }, - "deep-is": { + "node_modules/deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, - "default-require-extensions": { + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", + "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "dependencies": { + "kind-of": "^5.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-compare/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-require-extensions": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", - "requires": { - "strip-bom": "2.0.0" + "dependencies": { + "strip-bom": "^2.0.0" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dependencies": { - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "0.2.1" - } - } + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "defaults": { + "node_modules/default-resolution": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "requires": { - "clone": "1.0.2" + "dependencies": { + "clone": "^1.0.2" } }, - "del": { + "node_modules/defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", - "requires": { - "globby": "6.1.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "p-map": "1.1.1", - "pify": "3.0.0", - "rimraf": "2.6.1" + "dependencies": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "engines": { + "node": ">=4" } }, - "delayed-stream": { + "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } }, - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "engines": { + "node": ">= 0.6" + } }, - "deprecated": { + "node_modules/deprecated": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", - "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=" + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", + "engines": { + "node": ">= 0.9" + } }, - "destroy": { + "node_modules/destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, - "detect-file": { + "node_modules/detect-file": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "requires": { - "fs-exists-sync": "0.1.0" + "dependencies": { + "fs-exists-sync": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "detect-indent": { + "node_modules/detect-indent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "requires": { - "repeating": "2.0.1" + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "detect-newline": { + "node_modules/detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "engines": { + "node": ">=0.10.0" + } }, - "dicer": { + "node_modules/dicer": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", - "requires": { - "readable-stream": "1.1.14", + "dependencies": { + "readable-stream": "1.1.x", "streamsearch": "0.1.2" }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/dicer/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/dicer/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, - "diff": { + "node_modules/dicer/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/diff": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=" + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", + "engines": { + "node": ">=0.3.1" + } }, - "dns-prefetch-control": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz", - "integrity": "sha1-YN20V3dOF48flBXwyrsOhbCzALI=" + "node_modules/dns-prefetch-control": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz", + "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q==", + "engines": { + "node": ">=4.0.0" + } }, - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "dont-sniff-mimetype": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz", - "integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g=" + "node_modules/dom-walk": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "requires": { - "is-obj": "1.0.1" + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" } }, - "dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", - "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + "node_modules/dont-sniff-mimetype": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz", + "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==", + "engines": { + "node": ">=4.0.0" + } }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=" + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" + "node_modules/dot-prop/node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } }, - "duplexer2": { + "node_modules/dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=", + "engines": { + "node": ">=4.6.0" + } + }, + "node_modules/duplexer2": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "requires": { - "readable-stream": "1.1.14" - }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } + "readable-stream": "~1.1.9" } }, - "duplexer3": { + "node_modules/duplexer2/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/duplexer2/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "optional": true, - "requires": { - "jsbn": "0.1.1" + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" } }, - "ecdsa-sig-formatter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz", - "integrity": "sha1-S8kmJ07Dtau1AW5+HWCSGsJisqE=", - "requires": { - "base64url": "2.0.0", - "safe-buffer": "5.1.1" + "node_modules/duplexify/node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" } }, - "ee-first": { + "node_modules/each-props": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", + "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "dependencies": { + "is-plain-object": "^2.0.1", + "object.defaults": "^1.1.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, - "elegant-spinner": { + "node_modules/elegant-spinner": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "encodeurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", - "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, - "encoding": { + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "0.4.15" + "dependencies": { + "iconv-lite": "~0.4.13" } }, - "end-of-stream": { + "node_modules/end-of-stream": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", - "requires": { - "once": "1.3.3" - }, "dependencies": { - "once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", - "requires": { - "wrappy": "1.0.2" - } - } + "once": "~1.3.0" } }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "requires": { - "is-arrayish": "0.2.1" + "node_modules/end-of-stream/node_modules/once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dependencies": { + "wrappy": "1" } }, - "es5-ext": { - "version": "0.10.30", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz", - "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=", - "requires": { - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" + "node_modules/engine.io": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.0.tgz", + "integrity": "sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w==", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "0.3.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "^7.1.2" } }, - "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-symbol": "3.1.1" + "node_modules/engine.io-client": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.0.tgz", + "integrity": "sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA==", + "dependencies": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + } + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dependencies": { + "ms": "^2.1.1" } }, - "es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=" + "node_modules/engine.io-client/node_modules/ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "dependencies": { + "async-limiter": "~1.0.0" + } }, - "es6-symbol": { + "node_modules/engine.io-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "dependencies": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/envify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz", + "integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==", + "dependencies": { + "esprima": "^4.0.0", + "through": "~2.3.4" + }, + "bin": { + "envify": "bin/envify" + } + }, + "node_modules/envify/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es5-ext": { + "version": "0.10.49", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.49.tgz", + "integrity": "sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "^1.0.0" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "node_modules/es6-symbol": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30" + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" } }, - "es6-weak-map": { + "node_modules/es6-weak-map": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" + "dependencies": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" } }, - "escape-html": { + "node_modules/escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/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": { + "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } }, - "eslint": { + "node_modules/escodegen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", + "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.6.1.tgz", "integrity": "sha1-3cf8f9cL+TIFsLNEm7FqHp59SVA=", - "requires": { - "ajv": "5.2.2", - "babel-code-frame": "6.26.0", - "chalk": "2.1.0", - "concat-stream": "1.6.0", - "cross-spawn": "5.1.0", - "debug": "2.6.8", - "doctrine": "2.0.0", - "eslint-scope": "3.7.1", - "espree": "3.5.0", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.5", - "imurmurhash": "0.1.4", - "inquirer": "3.2.3", - "is-resolvable": "1.0.0", - "js-yaml": "3.9.1", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "4.0.0", - "progress": "2.0.0", - "require-uncached": "1.0.3", - "semver": "5.4.1", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", - "table": "4.0.1", - "text-table": "0.2.0" + "dependencies": { + "ajv": "^5.2.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^2.6.8", + "doctrine": "^2.0.0", + "eslint-scope": "^3.7.1", + "espree": "^3.5.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^9.17.0", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^4.0.0", + "progress": "^2.0.0", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "^4.0.1", + "text-table": "~0.2.0" }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.0.0.tgz", + "integrity": "sha512-/XlFQGn3Mkwm642/GYBtOH3pgFX4Z7saBsqqyp96v0bEUPq24nIrZ6N72qAoD0lR2wAne4EC4YsHYkbPfaRfiA==", "dependencies": { - "ansi-escapes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", - "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=" - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "requires": { - "color-convert": "1.9.0" - } - }, - "chalk": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", - "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==", - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.4.0" - } - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "requires": { - "restore-cursor": "2.0.0" - } - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" - }, - "external-editor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", - "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", - "requires": { - "iconv-lite": "0.4.18", - "jschardet": "1.5.1", - "tmp": "0.0.31" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "iconv-lite": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", - "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==" - }, - "inquirer": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.3.tgz", - "integrity": "sha512-Bc3KbimpDTOeQdDj18Ir/rlsGuhBSSNqdOnxaAuKhpkdnMMuKsEGbZD2v5KFF9oso2OU+BPh7+/u5obmFDRmWw==", - "requires": { - "ansi-escapes": "2.0.0", - "chalk": "2.1.0", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.0.4", - "figures": "2.0.0", - "lodash": "4.17.4", - "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "js-yaml": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz", - "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==", - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "requires": { - "mimic-fn": "1.1.0" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "3.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "requires": { - "has-flag": "2.0.0" - } - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "requires": { - "os-tmpdir": "1.0.2" - } - } + "eslint-restricted-globals": "^0.1.1" + }, + "engines": { + "node": ">= 4" } }, - "eslint-config-airbnb-base": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.0.0.tgz", - "integrity": "sha512-/XlFQGn3Mkwm642/GYBtOH3pgFX4Z7saBsqqyp96v0bEUPq24nIrZ6N72qAoD0lR2wAne4EC4YsHYkbPfaRfiA==", - "requires": { - "eslint-restricted-globals": "0.1.1" + "node_modules/eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dependencies": { + "debug": "^2.6.9", + "resolve": "^1.5.0" } }, - "eslint-import-resolver-node": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", - "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", - "requires": { - "debug": "2.6.8", - "resolve": "1.4.0" - }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - } + "ms": "2.0.0" } }, - "eslint-module-utils": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", - "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", - "requires": { - "debug": "2.6.8", - "pkg-dir": "1.0.0" + "node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/eslint-module-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz", + "integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==", + "dependencies": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - } + "ms": "2.0.0" } }, - "eslint-plugin-import": { + "node_modules/eslint-module-utils/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/eslint-plugin-import": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", - "requires": { - "builtin-modules": "1.1.1", - "contains-path": "0.1.0", - "debug": "2.6.8", + "dependencies": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.3.1", - "eslint-module-utils": "2.1.1", - "has": "1.0.1", - "lodash.cond": "4.5.2", - "minimatch": "3.0.4", - "read-pkg-up": "2.0.0" + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.1.1", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - } + "ms": "2.0.0" } }, - "eslint-restricted-globals": { + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/eslint-restricted-globals": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=" }, - "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", - "requires": { - "esrecurse": "4.2.0", - "estraverse": "4.2.0" + "node_modules/eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" } }, - "eslint-watch": { + "node_modules/eslint-watch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eslint-watch/-/eslint-watch-3.1.2.tgz", "integrity": "sha1-uTs+ygiRXxE9yQCZT4gNsTZN5LM=", - "requires": { - "babel-polyfill": "6.26.0", - "bluebird": "3.5.0", - "chalk": "1.1.3", - "chokidar": "1.7.0", - "debug": "2.6.8", - "keypress": "0.2.1", - "lodash": "4.17.4", - "optionator": "0.8.2", - "source-map-support": "0.4.17", - "text-table": "0.2.0", + "dependencies": { + "babel-polyfill": "^6.20.0", + "bluebird": "^3.4.7", + "chalk": "^1.1.3", + "chokidar": "^1.4.3", + "debug": "^2.6.3", + "keypress": "^0.2.1", + "lodash": "^4.17.4", + "optionator": "^0.8.2", + "source-map-support": "^0.4.14", + "text-table": "^0.2.0", "unicons": "0.0.3" }, - "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - } + "bin": { + "esw": "bin/esw" + }, + "engines": { + "node": ">=4" } }, - "espree": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz", - "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0=", - "requires": { - "acorn": "5.1.2", - "acorn-jsx": "3.0.1" + "node_modules/eslint-watch/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" } }, - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" - }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "requires": { - "estraverse": "4.2.0" + "node_modules/eslint-watch/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" + "node_modules/eslint-watch/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" } }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" - }, - "etag": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.0.tgz", - "integrity": "sha1-b2Ma7zNtbEY2K1F2QETOIWvjwFE=" + "node_modules/eslint-watch/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30" + "node_modules/eslint-watch/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" } }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", - "requires": { - "duplexer": "0.1.1", - "from": "0.1.7", - "map-stream": "0.1.0", - "pause-stream": "0.0.11", - "split": "0.3.3", - "stream-combiner": "0.0.4", - "through": "2.3.8" + "node_modules/eslint/node_modules/ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dependencies": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + "node_modules/eslint/node_modules/ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "engines": { + "node": ">=4" + } }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "node_modules/eslint/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "engines": { + "node": ">=4" } }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" + "node_modules/eslint/node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "requires": { - "is-posix-bracket": "0.1.1" + "node_modules/eslint/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" } }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "requires": { - "fill-range": "2.2.3" + "node_modules/eslint/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" } }, - "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", - "requires": { - "os-homedir": "1.0.2" + "node_modules/eslint/node_modules/external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "dependencies": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=0.12" } }, - "expect-ct": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.1.0.tgz", - "integrity": "sha1-UnNWeN4YUwiQ2Ne5XwrGNkCVgJQ=" + "node_modules/eslint/node_modules/fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" }, - "express": { - "version": "4.15.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.15.4.tgz", - "integrity": "sha1-Ay4iU0ic+PzgJma+yj0R7XotrtE=", - "requires": { - "accepts": "1.3.4", - "array-flatten": "1.1.1", - "content-disposition": "0.5.2", - "content-type": "1.0.2", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.8", - "depd": "1.1.1", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "etag": "1.8.0", - "finalhandler": "1.0.4", - "fresh": "0.5.0", - "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.1", - "path-to-regexp": "0.1.7", - "proxy-addr": "1.1.5", - "qs": "6.5.0", - "range-parser": "1.2.0", - "send": "0.15.4", - "serve-static": "1.12.4", - "setprototypeof": "1.0.3", - "statuses": "1.3.1", - "type-is": "1.6.15", - "utils-merge": "1.0.0", - "vary": "1.1.1" + "node_modules/eslint/node_modules/figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dependencies": { + "escape-string-regexp": "^1.0.5" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - }, - "qs": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz", - "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==" - } + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" } }, - "express-jwt": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.0.tgz", - "integrity": "sha1-PZDNZYAuYzYlLxnmo98+FJ4MXqA=", - "requires": { - "async": "1.5.2", - "express-unless": "0.3.1", - "jsonwebtoken": "7.4.3", - "lodash.set": "4.3.2" - }, + "node_modules/eslint/node_modules/inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "dependencies": { - "joi": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz", - "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=", - "requires": { - "hoek": "2.16.3", - "isemail": "1.2.0", - "moment": "2.18.1", - "topo": "1.1.0" - } - }, - "jsonwebtoken": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz", - "integrity": "sha1-d/UCHeBYtgWheD+hKD6ZgS5kVjg=", - "requires": { - "joi": "6.10.1", - "jws": "3.1.4", - "lodash.once": "4.1.1", - "ms": "2.0.0", - "xtend": "4.0.1" - } - } + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + } + }, + "node_modules/eslint/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "engines": { + "node": ">=4" } }, - "express-unless": { + "node_modules/eslint/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", - "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" }, - "express-validation": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/express-validation/-/express-validation-1.0.2.tgz", - "integrity": "sha1-fVid07JXxVs+AEZltsacsSzCsUI=", - "requires": { - "lodash": "4.17.4" - } + "node_modules/eslint/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "express-winston": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/express-winston/-/express-winston-2.4.0.tgz", - "integrity": "sha1-J6ts2TBT4t/cNbzuoUoHfcfVLkk=", - "requires": { - "chalk": "0.4.0", - "lodash": "4.11.2" - }, + "node_modules/eslint/node_modules/mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "node_modules/eslint/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dependencies": { - "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=" - }, - "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "requires": { - "ansi-styles": "1.0.0", - "has-color": "0.1.7", - "strip-ansi": "0.1.1" - } - }, - "lodash": { - "version": "4.11.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.11.2.tgz", - "integrity": "sha1-1rQzixEKWOIdrlzrz9u/0rxM2zs=" - }, - "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=" - } + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" - }, - "external-editor": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-1.1.1.tgz", - "integrity": "sha1-Etew24UPf/fnCBuvQAVwAGDEYAs=", - "requires": { - "extend": "3.0.1", - "spawn-sync": "1.0.15", - "tmp": "0.0.29" + "node_modules/eslint/node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" } }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "requires": { - "is-extglob": "1.0.0" + "node_modules/eslint/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + "node_modules/eslint/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, - "fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", - "requires": { - "chalk": "1.1.3", - "time-stamp": "1.1.0" + "node_modules/eslint/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" } }, - "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + "node_modules/espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dependencies": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" + "node_modules/esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dependencies": { + "estraverse": "^4.0.0" + }, + "engines": { + "node": ">=0.6" } }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "requires": { - "flat-cache": "1.2.2", - "object-assign": "4.1.1" + "node_modules/esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dependencies": { + "estraverse": "^4.1.0" + }, + "engines": { + "node": ">=4.0" } }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + "node_modules/estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "engines": { + "node": ">=0.10.0" + } }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", - "requires": { - "glob": "7.1.2", - "minimatch": "3.0.4" + "node_modules/esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "engines": { + "node": ">=0.10.0" } }, - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "engines": { + "node": ">= 0.6" } }, - "finalhandler": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.4.tgz", - "integrity": "sha512-16l/r8RgzlXKmFOhZpHBztvye+lAhC5SU7hXavnerC9UfZqZxxXl3BzL8MhffPT3kF61lj9Oav2LKEzh0ei7tg==", - "requires": { - "debug": "2.6.8", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.1", - "statuses": "1.3.1", - "unpipe": "1.0.0" - }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "requires": { - "ms": "2.0.0" - } - } + "d": "1", + "es5-ext": "~0.10.14" } }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=" + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, - "find-node-modules": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-1.0.4.tgz", - "integrity": "sha1-tt6zzMtpnIcDdne87eLF9YYrJVA=", - "requires": { - "findup-sync": "0.4.2", - "merge": "1.2.0" + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" } }, - "find-parent-dir": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", - "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=" - }, - "find-root": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.0.0.tgz", - "integrity": "sha1-li/yEaqyXGUg/u641ih/j26VgHo=" - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "node_modules/exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "engines": { + "node": ">=0.10.0" } }, - "findup": { + "node_modules/expand-brackets": { "version": "0.1.5", - "resolved": "https://registry.npmjs.org/findup/-/findup-0.1.5.tgz", - "integrity": "sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs=", - "requires": { - "colors": "0.6.2", - "commander": "2.1.0" - }, + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dependencies": { - "colors": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=" - }, - "commander": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz", - "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=" - } + "is-posix-bracket": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "findup-sync": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.2.tgz", - "integrity": "sha1-qBF9D3MST1pFRoOVef5S1xKfteU=", - "requires": { - "detect-file": "0.1.0", - "is-glob": "2.0.1", - "micromatch": "2.3.11", - "resolve-dir": "0.1.1" + "node_modules/expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dependencies": { + "fill-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "fined": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", - "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", - "requires": { - "expand-tilde": "2.0.2", - "is-plain-object": "2.0.4", - "object.defaults": "1.1.0", - "object.pick": "1.3.0", - "parse-filepath": "1.0.1" - }, + "node_modules/expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", "dependencies": { - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "requires": { - "homedir-polyfill": "1.0.1" - } - } + "os-homedir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "first-chunk-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" - }, - "flagged-respawn": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", - "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=" + "node_modules/expect-ct": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz", + "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g==", + "engines": { + "node": ">=4.0.0" + } }, - "flat-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "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.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express-jwt": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.1.tgz", + "integrity": "sha512-1C9RNq0wMp/JvsH/qZMlg3SIPvKu14YkZ4YYv7gJQ1Vq+Dv8LH9tLKenS5vMNth45gTlEUGx+ycp9IHIlaHP/g==", "dependencies": { - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.1" - } - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } + "async": "^1.5.0", + "express-unless": "^0.3.0", + "jsonwebtoken": "^8.1.0", + "lodash.set": "^4.0.0" + }, + "engines": { + "node": ">= 0.4.0" } }, - "follow-redirects": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz", - "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==", - "requires": { - "debug": "3.1.0" - }, + "node_modules/express-jwt/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "node_modules/express-jwt/node_modules/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - } + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" } }, - "for-in": { + "node_modules/express-unless": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", + "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" + }, + "node_modules/express-validation": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + "resolved": "https://registry.npmjs.org/express-validation/-/express-validation-1.0.2.tgz", + "integrity": "sha1-fVid07JXxVs+AEZltsacsSzCsUI=", + "dependencies": { + "lodash": "^4.9.0" + } }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "requires": { - "for-in": "1.0.2" + "node_modules/express-winston": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/express-winston/-/express-winston-2.4.0.tgz", + "integrity": "sha1-J6ts2TBT4t/cNbzuoUoHfcfVLkk=", + "dependencies": { + "chalk": "~0.4.0", + "lodash": "~4.11.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "node_modules/express-winston/node_modules/ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "engines": { + "node": ">=0.8.0" + } }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.17" + "node_modules/express-winston/node_modules/chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dependencies": { + "ansi-styles": "~1.0.0", + "has-color": "~0.1.0", + "strip-ansi": "~0.1.0" + }, + "engines": { + "node": ">=0.8.0" } }, - "format-util": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.3.tgz", - "integrity": "sha1-Ay3KShFiYqEsQ/TD7IVmQWxbLZU=" + "node_modules/express-winston/node_modules/lodash": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.11.2.tgz", + "integrity": "sha1-1rQzixEKWOIdrlzrz9u/0rxM2zs=" }, - "formidable": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.1.1.tgz", - "integrity": "sha1-lriIb3w8NQi5Mta9cMTTqI818ak=" + "node_modules/express-winston/node_modules/strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "bin": { + "strip-ansi": "cli.js" + }, + "engines": { + "node": ">=0.8.0" + } }, - "forwarded": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.0.tgz", - "integrity": "sha1-Ge+YdMSuHCl7zweP3mOgm2aoQ2M=" + "node_modules/express/node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } }, - "frameguard": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.0.0.tgz", - "integrity": "sha1-e8rUae57lukdEs6zlZx4I1qScuk=" + "node_modules/express/node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } }, - "fresh": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.0.tgz", - "integrity": "sha1-9HTKXmqSRtb9jglTz6m5yAWvp44=" + "node_modules/express/node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=" + "node_modules/express/node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "engines": { + "node": ">= 0.6" + } }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } }, - "fs-extra": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", - "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1" + "node_modules/express/node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" } }, - "fs-readdir-recursive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.0.0.tgz", - "integrity": "sha1-jNF0XItPiinIyuw5JHaSG6GV9WA=" + "node_modules/express/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "node_modules/express/node_modules/mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "engines": { + "node": ">= 0.6" + } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "node_modules/express/node_modules/mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dependencies": { + "mime-db": "1.40.0" + }, + "engines": { + "node": ">= 0.6" + } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "gaze": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", - "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", - "requires": { - "globule": "0.1.0" + "node_modules/express/node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "engines": { + "node": ">= 0.6" } }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=" + "node_modules/express/node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "requires": { - "is-property": "1.0.2" + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "engines": { + "node": ">=0.6" } }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + "node_modules/express/node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } }, - "get-own-enumerable-property-symbols": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz", - "integrity": "sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug==", - "dev": true + "node_modules/express/node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + "node_modules/express/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "1.0.0" + "node_modules/express/node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" } }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "node_modules/external-editor": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-1.1.1.tgz", + "integrity": "sha1-Etew24UPf/fnCBuvQAVwAGDEYAs=", + "dependencies": { + "extend": "^3.0.0", + "spawn-sync": "^1.0.15", + "tmp": "^0.0.29" } }, - "glob-base": { + "node_modules/extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "engines": { + "node": "> 0.1.90" + } + }, + "node_modules/fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dependencies": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "node_modules/feature-policy": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", + "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==", + "engines": { + "node": ">=4.0.0" } }, - "glob-parent": { + "node_modules/figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dependencies": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/file-entry-cache": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "requires": { - "is-glob": "2.0.1" + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dependencies": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "requires": { - "glob": "4.5.3", - "glob2base": "0.0.12", - "minimatch": "2.0.10", - "ordered-read-streams": "0.1.0", - "through2": "0.6.5", - "unique-stream": "1.0.0" + "node_modules/filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dependencies": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "node_modules/fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dependencies": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "requires": { - "brace-expansion": "1.1.8" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "glob-watcher": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", - "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", - "requires": { - "gaze": "0.5.2" + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" } }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "requires": { - "find-index": "0.1.1" - } + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", - "requires": { - "global-prefix": "0.1.5", - "is-windows": "0.2.0" + "node_modules/finalhandler/node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" } }, - "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", - "requires": { - "homedir-polyfill": "1.0.1", - "ini": "1.3.4", - "is-windows": "0.2.0", - "which": "1.3.0" + "node_modules/find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=" + }, + "node_modules/find-node-modules": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-1.0.4.tgz", + "integrity": "sha1-tt6zzMtpnIcDdne87eLF9YYrJVA=", + "dependencies": { + "findup-sync": "0.4.2", + "merge": "^1.2.0" } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + "node_modules/find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=" }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "requires": { - "array-union": "1.0.2", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, + "node_modules/find-root": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.0.0.tgz", + "integrity": "sha1-li/yEaqyXGUg/u641ih/j26VgHo=" + }, + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - } + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "requires": { - "glob": "3.1.21", - "lodash": "1.0.2", - "minimatch": "0.2.14" + "node_modules/findup": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/findup/-/findup-0.1.5.tgz", + "integrity": "sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs=", + "dependencies": { + "colors": "~0.6.0-1", + "commander": "~2.1.0" }, + "bin": { + "findup": "bin/findup.js" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/findup-sync": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.2.tgz", + "integrity": "sha1-qBF9D3MST1pFRoOVef5S1xKfteU=", "dependencies": { - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "requires": { - "graceful-fs": "1.2.3", - "inherits": "1.0.2", - "minimatch": "0.2.14" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=" - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=" - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=" - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - } + "detect-file": "^0.1.0", + "is-glob": "^2.0.1", + "micromatch": "^2.3.7", + "resolve-dir": "^0.1.0" + }, + "engines": { + "node": ">= 0.8.0" } }, - "glogg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", - "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", - "requires": { - "sparkles": "1.0.0" + "node_modules/findup/node_modules/colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", + "engines": { + "node": ">=0.1.90" } }, - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "requires": { - "create-error-class": "3.0.2", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.0", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" + "node_modules/findup/node_modules/commander": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz", + "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=", + "engines": { + "node": ">= 0.6.x" } }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + "node_modules/fined": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz", + "integrity": "sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==", + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } }, - "graceful-readlink": { + "node_modules/fined/node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flagged-respawn": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "engines": { + "node": ">= 0.10" + } }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=" + "node_modules/flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "dependencies": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "gulp": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", - "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", - "requires": { - "archy": "1.0.0", - "chalk": "1.1.3", - "deprecated": "0.0.1", - "gulp-util": "3.0.8", - "interpret": "1.0.3", - "liftoff": "2.3.0", - "minimist": "1.2.0", - "orchestrator": "0.3.8", - "pretty-hrtime": "1.0.3", - "semver": "4.3.6", - "tildify": "1.2.0", - "v8flags": "2.1.1", - "vinyl-fs": "0.3.14" + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dependencies": { + "debug": "=3.1.0" }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/follow-redirects/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" - } + "ms": "2.0.0" } }, - "gulp-babel": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-7.0.0.tgz", - "integrity": "sha512-TiUuFLW6FD2hx3mJ7QBPXN2nzpu6gRWFyjfChWxE1A9xaASRA5nsxrvHcqMDl5Ha6TvSBB9r74GbkVd1GO4mDA==", - "requires": { - "gulp-util": "3.0.8", - "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl-sourcemaps-apply": "0.2.1" + "node_modules/follow-redirects/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "engines": { + "node": ">=0.10.0" } }, - "gulp-load-plugins": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/gulp-load-plugins/-/gulp-load-plugins-1.5.0.tgz", - "integrity": "sha1-TEGffldk2aDjMGG6uWGPgbc9QXE=", - "requires": { - "array-unique": "0.2.1", - "fancy-log": "1.3.0", - "findup-sync": "0.4.2", - "gulplog": "1.0.0", - "has-gulplog": "0.1.0", - "micromatch": "2.3.11", - "resolve": "1.4.0" + "node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "gulp-newer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/gulp-newer/-/gulp-newer-1.3.0.tgz", - "integrity": "sha1-1Q7Ky7gi7aSStXMkpshaB/2aVcE=", - "requires": { - "glob": "7.1.2", - "gulp-util": "3.0.8", - "kew": "0.7.0" + "node_modules/foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "engines": { + "node": "*" } }, - "gulp-nodemon": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/gulp-nodemon/-/gulp-nodemon-2.2.1.tgz", - "integrity": "sha1-2b8Zn1WFRYFZ09KZFT5gtGhotvQ=", - "requires": { - "colors": "1.1.2", - "event-stream": "3.3.4", - "gulp": "3.9.1", - "nodemon": "1.12.0" + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/format-util": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.3.tgz", + "integrity": "sha1-Ay3KShFiYqEsQ/TD7IVmQWxbLZU=" + }, + "node_modules/formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/frameguard": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz", + "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dependencies": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/fsevents/node_modules/ansi-regex": { + "version": "2.1.1", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/aproba": { + "version": "1.2.0", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, + "node_modules/fsevents/node_modules/are-we-there-yet": { + "version": "1.1.5", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "optional": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/fsevents/node_modules/balanced-match": { + "version": "1.0.0", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "optional": true + }, + "node_modules/fsevents/node_modules/brace-expansion": { + "version": "1.1.11", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fsevents/node_modules/chownr": { + "version": "1.1.1", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "optional": true + }, + "node_modules/fsevents/node_modules/code-point-at": { + "version": "1.1.0", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/concat-map": { + "version": "0.0.1", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "optional": true + }, + "node_modules/fsevents/node_modules/console-control-strings": { + "version": "1.1.0", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true + }, + "node_modules/fsevents/node_modules/core-util-is": { + "version": "1.0.2", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "optional": true + }, + "node_modules/fsevents/node_modules/debug": { + "version": "4.1.1", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/fsevents/node_modules/delegates": { + "version": "1.0.0", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true + }, + "node_modules/fsevents/node_modules/detect-libc": { + "version": "1.0.3", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/fsevents/node_modules/fs-minipass": { + "version": "1.2.5", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "optional": true, + "dependencies": { + "minipass": "^2.2.1" + } + }, + "node_modules/fsevents/node_modules/fs.realpath": { + "version": "1.0.0", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "optional": true + }, + "node_modules/fsevents/node_modules/gauge": { + "version": "2.7.4", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/fsevents/node_modules/glob": { + "version": "7.1.3", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "optional": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fsevents/node_modules/has-unicode": { + "version": "2.0.1", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true + }, + "node_modules/fsevents/node_modules/iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/ignore-walk": { + "version": "3.0.1", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "optional": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/fsevents/node_modules/inflight": { + "version": "1.0.6", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "optional": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/fsevents/node_modules/inherits": { + "version": "2.0.3", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "optional": true + }, + "node_modules/fsevents/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/isarray": { + "version": "1.0.0", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "optional": true + }, + "node_modules/fsevents/node_modules/minimatch": { + "version": "3.0.4", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "optional": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/fsevents/node_modules/minimist": { + "version": "0.0.8", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "optional": true + }, + "node_modules/fsevents/node_modules/minipass": { + "version": "2.3.5", + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "optional": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/fsevents/node_modules/minizlib": { + "version": "1.2.1", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "optional": true, + "dependencies": { + "minipass": "^2.2.1" + } + }, + "node_modules/fsevents/node_modules/mkdirp": { + "version": "0.5.1", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "optional": true, + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/fsevents/node_modules/ms": { + "version": "2.1.1", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "optional": true + }, + "node_modules/fsevents/node_modules/needle": { + "version": "2.3.0", + "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", + "optional": true, + "dependencies": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/fsevents/node_modules/node-pre-gyp": { + "version": "0.12.0", + "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/fsevents/node_modules/nopt": { + "version": "4.0.1", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "optional": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/fsevents/node_modules/npm-bundled": { + "version": "1.0.6", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", + "optional": true + }, + "node_modules/fsevents/node_modules/npm-packlist": { + "version": "1.4.1", + "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "optional": true, + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "node_modules/fsevents/node_modules/npmlog": { + "version": "4.1.2", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/fsevents/node_modules/number-is-nan": { + "version": "1.0.1", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/object-assign": { + "version": "4.1.1", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/once": { + "version": "1.4.0", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "optional": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/fsevents/node_modules/os-homedir": { + "version": "1.0.2", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/os-tmpdir": { + "version": "1.0.2", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/osenv": { + "version": "0.1.5", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "optional": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/fsevents/node_modules/path-is-absolute": { + "version": "1.0.1", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/process-nextick-args": { + "version": "2.0.0", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "optional": true + }, + "node_modules/fsevents/node_modules/readable-stream": { + "version": "2.3.6", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/fsevents/node_modules/rimraf": { + "version": "2.6.3", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "optional": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/fsevents/node_modules/safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "node_modules/fsevents/node_modules/safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "optional": true + }, + "node_modules/fsevents/node_modules/sax": { + "version": "1.2.4", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "optional": true + }, + "node_modules/fsevents/node_modules/set-blocking": { + "version": "2.0.0", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "optional": true + }, + "node_modules/fsevents/node_modules/signal-exit": { + "version": "3.0.2", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "optional": true + }, + "node_modules/fsevents/node_modules/string_decoder": { + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/fsevents/node_modules/string-width": { + "version": "1.0.2", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/strip-ansi": { + "version": "3.0.1", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fsevents/node_modules/tar": { + "version": "4.4.8", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/fsevents/node_modules/util-deprecate": { + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "optional": true + }, + "node_modules/fsevents/node_modules/wide-align": { + "version": "1.1.3", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "optional": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/fsevents/node_modules/wrappy": { + "version": "1.0.2", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "optional": true + }, + "node_modules/fsevents/node_modules/yallist": { + "version": "3.0.3", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "optional": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "node_modules/gaze": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "dependencies": { + "globule": "~0.1.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "dependencies": { + "is-property": "^1.0.0" + } + }, + "node_modules/get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "engines": { + "node": "*" + } + }, + "node_modules/get-own-enumerable-property-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", + "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==", + "dev": true + }, + "node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dependencies": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dependencies": { + "is-glob": "^2.0.0" + } + }, + "node_modules/glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "dependencies": { + "glob": "^4.3.1", + "glob2base": "^0.0.12", + "minimatch": "^2.0.1", + "ordered-read-streams": "^0.1.0", + "through2": "^0.6.1", + "unique-stream": "^1.0.0" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/glob-stream/node_modules/glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/glob-stream/node_modules/minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dependencies": { + "brace-expansion": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-stream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/glob-stream/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/glob-stream/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/glob-watcher": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "dependencies": { + "gaze": "^0.5.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "dependencies": { + "find-index": "^0.1.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "dependencies": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "node_modules/global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "dependencies": { + "ini": "1.3.7" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/global-dirs/node_modules/ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" + }, + "node_modules/global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "dependencies": { + "global-prefix": "^0.1.4", + "is-windows": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-modules/node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "dependencies": { + "homedir-polyfill": "^1.0.0", + "ini": "^1.3.4", + "is-windows": "^0.2.0", + "which": "^1.2.12" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/globule": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "dependencies": { + "glob": "~3.1.21", + "lodash": "~1.0.1", + "minimatch": "~0.2.11" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/globule/node_modules/glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "dependencies": { + "graceful-fs": "~1.2.0", + "inherits": "1", + "minimatch": "~0.2.11" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globule/node_modules/graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/globule/node_modules/inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=" + }, + "node_modules/globule/node_modules/lodash": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", + "engines": [ + "node", + "rhino" + ] + }, + "node_modules/globule/node_modules/lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + }, + "node_modules/globule/node_modules/minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dependencies": { + "lru-cache": "2", + "sigmund": "~1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "dependencies": { + "sparkles": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dependencies": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/got/node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/got/node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/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==" + }, + "node_modules/graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "node_modules/growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=" + }, + "node_modules/gulp": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "dependencies": { + "archy": "^1.0.0", + "chalk": "^1.0.0", + "deprecated": "^0.0.1", + "gulp-util": "^3.0.0", + "interpret": "^1.0.0", + "liftoff": "^2.1.0", + "minimist": "^1.1.0", + "orchestrator": "^0.3.0", + "pretty-hrtime": "^1.0.0", + "semver": "^4.1.0", + "tildify": "^1.0.0", + "v8flags": "^2.0.2", + "vinyl-fs": "^0.3.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/gulp-babel": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-7.0.0.tgz", + "integrity": "sha512-TiUuFLW6FD2hx3mJ7QBPXN2nzpu6gRWFyjfChWxE1A9xaASRA5nsxrvHcqMDl5Ha6TvSBB9r74GbkVd1GO4mDA==", + "dependencies": { + "gulp-util": "^3.0.0", + "replace-ext": "0.0.1", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/gulp-cli": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", + "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", + "dependencies": { + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.4.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.2.0", + "yargs": "^7.1.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-cli/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/gulp-cli/node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-cli/node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "dependencies": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/gulp-cli/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/gulp-cli/node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-cli/node_modules/v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-load-plugins": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/gulp-load-plugins/-/gulp-load-plugins-1.5.0.tgz", + "integrity": "sha1-TEGffldk2aDjMGG6uWGPgbc9QXE=", + "dependencies": { + "array-unique": "^0.2.1", + "fancy-log": "^1.2.0", + "findup-sync": "^0.4.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "micromatch": "^2.3.8", + "resolve": "^1.1.7" + } + }, + "node_modules/gulp-newer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/gulp-newer/-/gulp-newer-1.3.0.tgz", + "integrity": "sha1-1Q7Ky7gi7aSStXMkpshaB/2aVcE=", + "dependencies": { + "glob": "^7.0.3", + "gulp-util": "^3.0.7", + "kew": "^0.7.0" + } + }, + "node_modules/gulp-nodemon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/gulp-nodemon/-/gulp-nodemon-2.5.0.tgz", + "integrity": "sha512-vXfaP72xo2C6XOaXrNcLEM3QqDJ1x21S3x97U4YtzN2Rl2kH57++aFkAVxe6BafGRSTxs/xVfE/jNNlCv5Ym2Q==", + "dependencies": { + "colors": "^1.2.1", + "gulp": "^4.0.0", + "nodemon": "^2.0.2" + } + }, + "node_modules/gulp-nodemon/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/gulp-nodemon/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/gulp-nodemon/node_modules/chokidar/node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/gulp-nodemon/node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + }, + "node_modules/gulp-nodemon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/gulp-nodemon/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dependencies": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/glob-watcher": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", + "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", + "dependencies": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "object.defaults": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "dependencies": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-nodemon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/gulp-nodemon/node_modules/ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/gulp-nodemon/node_modules/replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "node_modules/gulp-nodemon/node_modules/vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-nodemon/node_modules/vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dependencies": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-sourcemaps": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.1.tgz", + "integrity": "sha512-1qHCI3hdmsMdq/SUotxwUh/L8YzlI6J9zQ5ifNOtx4Y6KV5y5sGuORv1KZzWhuKtz/mXNh5xLESUtwC4EndCjA==", + "dependencies": { + "@gulp-sourcemaps/identity-map": "1.X", + "@gulp-sourcemaps/map-sources": "1.X", + "acorn": "4.X", + "convert-source-map": "1.X", + "css": "2.X", + "debug-fabulous": ">=0.1.1", + "detect-newline": "2.X", + "graceful-fs": "4.X", + "source-map": "0.X", + "strip-bom-string": "1.X", + "through2": "2.X", + "vinyl": "1.X" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/gulp-sourcemaps/node_modules/acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/gulp-sourcemaps/node_modules/vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dependencies": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/gulp-util": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", + "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dependencies": { + "array-differ": "^1.0.0", + "array-uniq": "^1.0.2", + "beeper": "^1.0.0", + "chalk": "^1.0.0", + "dateformat": "^2.0.0", + "fancy-log": "^1.1.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "lodash._reescape": "^3.0.0", + "lodash._reevaluate": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.template": "^3.0.0", + "minimist": "^1.1.0", + "multipipe": "^0.1.2", + "object-assign": "^3.0.0", + "replace-ext": "0.0.1", + "through2": "^2.0.0", + "vinyl": "^0.5.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/gulp-util/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-util/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-util/node_modules/object-assign": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-util/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/gulp/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp/node_modules/semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/gulp/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/gulplog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", + "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dependencies": { + "glogg": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/handlebars": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dependencies": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dependencies": { + "isarray": "2.0.1" + } + }, + "node_modules/has-binary2/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "node_modules/has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-gulplog": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", + "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dependencies": { + "sparkles": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-value/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "engines": { + "node": ">=8" + } + }, + "node_modules/hawk": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", + "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "dependencies": { + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" + }, + "engines": { + "node": ">=0.10.32" + } + }, + "node_modules/helmet": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz", + "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==", + "dependencies": { + "depd": "2.0.0", + "dns-prefetch-control": "0.2.0", + "dont-sniff-mimetype": "1.1.0", + "expect-ct": "0.2.0", + "feature-policy": "0.3.0", + "frameguard": "3.1.0", + "helmet-crossdomain": "0.4.0", + "helmet-csp": "2.9.2", + "hide-powered-by": "1.1.0", + "hpkp": "2.0.0", + "hsts": "2.2.0", + "ienoopen": "1.1.0", + "nocache": "2.1.0", + "referrer-policy": "1.2.0", + "x-xss-protection": "1.3.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/helmet-crossdomain": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz", + "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/helmet-csp": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz", + "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==", + "dependencies": { + "bowser": "^2.6.1", + "camelize": "1.0.0", + "content-security-policy-builder": "2.1.0", + "dasherize": "2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/helmet/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/hide-powered-by": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz", + "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/hoek": { + "version": "2.16.3", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", + "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", + "engines": { + "node": ">=0.10.40" + } + }, + "node_modules/home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hooks-fixed": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hooks-fixed/-/hooks-fixed-2.0.0.tgz", + "integrity": "sha1-oB2JTVKsf2WZu7H2PfycQR33DLo=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + }, + "node_modules/hpkp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz", + "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" + }, + "node_modules/hsts": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", + "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", + "dependencies": { + "depd": "2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/hsts/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/http": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/http/-/http-0.0.1-security.tgz", + "integrity": "sha512-RnDvP10Ty9FxqOtPZuxtebw1j4L/WiqNMDtuc1YMH1XQm5TgDRaR1G9u8upL6KD1bXHSp9eSXo/ED+8Q7FAr+g==" + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "node_modules/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=", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.6.tgz", + "integrity": "sha512-NyL6ZB6cVni7pl+/IT2W0ni5ME00xR0sN27AQZZrpKn1b+qRh+mLbBxIq9Cq1oGfmTc7BUq4HB77mxwCaxAYNg==", + "dependencies": { + "@types/http-proxy": "^1.17.4", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.20", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-proxy-middleware/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/http-proxy-middleware/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/http-status": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.0.1.tgz", + "integrity": "sha1-3EMAGov8UKyH1IWokvdXiWS8lKI=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha1-PDfHrhqO65ZpBKKtHpdaGUt+06Q=" + }, + "node_modules/https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "dependencies": { + "agent-base": "5", + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/https-proxy-agent/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/husky": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", + "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", + "dev": true, + "dependencies": { + "is-ci": "^1.0.10", + "normalize-path": "^1.0.0", + "strip-indent": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/husky/node_modules/normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", + "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", + "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" + }, + "node_modules/ienoopen": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", + "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" + }, + "node_modules/import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/inquirer": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-1.2.3.tgz", + "integrity": "sha1-TexvMvN+97sLLtPx0aXD9UUHSRg=", + "dependencies": { + "ansi-escapes": "^1.1.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "external-editor": "^1.1.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", + "mute-stream": "0.0.6", + "pinkie-promise": "^2.0.0", + "run-async": "^2.2.0", + "rx": "^4.1.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + } + }, + "node_modules/inquirer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inquirer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "dependencies": { + "ci-info": "^1.5.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dependencies": { + "is-primitive": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "dependencies": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-installed-globally/node_modules/is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==" + }, + "node_modules/is-my-json-valid": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", + "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", + "dependencies": { + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", + "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", + "dev": true, + "dependencies": { + "symbol-observable": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dependencies": { + "is-path-inside": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dependencies": { + "path-is-inside": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=" + }, + "node_modules/is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" + }, + "node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "node_modules/istanbul": { + "version": "1.0.0-alpha.2", + "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-1.0.0-alpha.2.tgz", + "integrity": "sha1-BglrwI6Yuq10Sq5Gli2N+frGPQg=", + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "istanbul-api": "^1.0.0-alpha", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/istanbul-api": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", + "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", + "dependencies": { + "async": "^2.1.4", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.1", + "istanbul-lib-hook": "^1.2.2", + "istanbul-lib-instrument": "^1.10.2", + "istanbul-lib-report": "^1.1.5", + "istanbul-lib-source-maps": "^1.2.6", + "istanbul-reports": "^1.5.1", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + } + }, + "node_modules/istanbul-api/node_modules/async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "dependencies": { + "lodash": "^4.17.11" + } + }, + "node_modules/istanbul-api/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/istanbul-api/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==" + }, + "node_modules/istanbul-lib-hook": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", + "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", + "dependencies": { + "append-transform": "^0.4.0" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", + "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", + "dependencies": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.1", + "semver": "^5.3.0" + } + }, + "node_modules/istanbul-lib-report": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", + "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", + "dependencies": { + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", + "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", + "dependencies": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/istanbul-reports": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", + "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", + "dependencies": { + "handlebars": "^4.0.3" + } + }, + "node_modules/istanbul/node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=" + }, + "node_modules/istanbul/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "node_modules/istanbul/node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/items": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/items/-/items-2.1.2.tgz", + "integrity": "sha512-kezcEqgB97BGeZZYtX/MA8AG410ptURstvnz5RAgyFZ8wQFPMxHY8GpTq+/ZHKT3frSlIthUq7EvLt9xn3TvXg==" + }, + "node_modules/jest-get-type": { + "version": "21.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz", + "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==", + "dev": true + }, + "node_modules/jest-validate": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz", + "integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1", + "jest-get-type": "^21.2.0", + "leven": "^2.1.0", + "pretty-format": "^21.2.1" + } + }, + "node_modules/jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/joi": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-10.6.0.tgz", + "integrity": "sha512-hBF3LcqyAid+9X/pwg+eXjD2QBZI5eXnBFJYaAkH4SK3mp9QSRiiQnDYlmlz5pccMvnLcJRS4whhDOTCkmsAdQ==", + "dependencies": { + "hoek": "4.x.x", + "isemail": "2.x.x", + "items": "2.x.x", + "topo": "2.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/joi/node_modules/hoek": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/joi/node_modules/isemail": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-2.2.1.tgz", + "integrity": "sha1-A1PT2aYpUQgMJiwqoKQrjqjp4qY=", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/joi/node_modules/topo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz", + "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", + "dependencies": { + "hoek": "4.x.x" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "node_modules/jsdom": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.0.tgz", + "integrity": "sha512-6VaW3UWyKbm9DFVIAgTfhuwnvqiqlRYNg5Rk6dINTVoZT0eKz+N86vQZr+nqt1ny1lSB1TWZJWSEWQAfu8oTpA==", + "dependencies": { + "abab": "^2.0.3", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.4", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.13.0", + "html-encoding-sniffer": "^2.0.0", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.0", + "request-promise-native": "^1.0.8", + "saxes": "^4.0.2", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^5.0.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.1", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsdom/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "node_modules/json-schema-ref-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-1.4.1.tgz", + "integrity": "sha1-wMLkOL8HlnI7AkUbrovH3Qs3/tA=", + "dependencies": { + "call-me-maybe": "^1.0.1", + "debug": "^2.2.0", + "es6-promise": "^3.0.2", + "js-yaml": "^3.4.6", + "ono": "^2.0.1" + } + }, + "node_modules/json-schema-ref-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/json-schema-ref-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/json-schema-ref-parser/node_modules/ono": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/ono/-/ono-2.2.5.tgz", + "integrity": "sha1-2vCUiLURdNp6fkJ136sxtDj/oOM=" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "node_modules/json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=" + }, + "node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "node_modules/jsonpointer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", + "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jsonwebtoken": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.0.0.tgz", + "integrity": "sha1-eyQapnxhs9Cz5kElSppvW2b1UOg=", + "dependencies": { + "jws": "^3.1.4", + "lodash.includes": "^4.3.0", + "lodash.isarray": "^4.0.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.0.0", + "xtend": "^4.0.1" + }, + "engines": { + "node": ">=0.12", + "npm": ">=1.4.28" + } + }, + "node_modules/jsonwebtoken/node_modules/lodash.isarray": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-4.0.0.tgz", + "integrity": "sha1-KspJayjEym1yZxUxNZDALm6jRAM=" + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/jstoxml": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/jstoxml/-/jstoxml-1.6.7.tgz", + "integrity": "sha512-XTVwGdi/saJtJgiLvl9Fi/J7GsFuRiOER52QIlYv+10vq2LANx/l+d/AvbAF2kF3UOQF2dkW09WzqKH1z148XQ==" + }, + "node_modules/just-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", + "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=" + }, + "node_modules/just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/kareem": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-1.5.0.tgz", + "integrity": "sha1-4+QQHZ3P3imXadr0tNtk2JXRdEg=" + }, + "node_modules/kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=" + }, + "node_modules/keypress": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", + "integrity": "sha1-HoBFQlABjbrUw/6USX1uZ7YmnHc=" + }, + "node_modules/keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/last-run": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", + "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "dependencies": { + "default-resolution": "^2.0.0", + "es6-weak-map": "^2.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dependencies": { + "package-json": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lcov-parse": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", + "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=" + }, + "node_modules/lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dependencies": { + "flush-write-stream": "^1.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/liftoff": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "dependencies": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/liftoff/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/liftoff/node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/liftoff/node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/liftoff/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/liftoff/node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lint-staged": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-6.1.1.tgz", + "integrity": "sha512-M/7bwLdXbeG7ZNLcasGeLMBDg60/w6obj3KOtINwJyxAxb53XGY0yH5FSZlWklEzuVbTtqtIfAajh6jYIN90AA==", + "dev": true, + "dependencies": { + "app-root-path": "^2.0.0", + "chalk": "^2.1.0", + "commander": "^2.11.0", + "cosmiconfig": "^4.0.0", + "debug": "^3.1.0", + "dedent": "^0.7.0", + "execa": "^0.8.0", + "find-parent-dir": "^0.3.0", + "is-glob": "^4.0.0", + "jest-validate": "^21.1.0", + "listr": "^0.13.0", + "lodash": "^4.17.4", + "log-symbols": "^2.0.0", + "minimatch": "^3.0.0", + "npm-which": "^3.0.1", + "p-map": "^1.1.1", + "path-is-inside": "^1.0.2", + "pify": "^3.0.0", + "staged-git-files": "1.0.0", + "stringify-object": "^3.2.0" + }, + "bin": { + "lint-staged": "index.js" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/lint-staged/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/lint-staged/node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/lint-staged/node_modules/execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "dev": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lint-staged/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lint-staged/node_modules/is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.13.0.tgz", + "integrity": "sha1-ILsLowuuZg7oTMBQPfS+PVYjiH0=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-observable": "^0.2.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.4.0", + "listr-verbose-renderer": "^0.4.0", + "log-symbols": "^1.0.2", + "log-update": "^1.0.2", + "ora": "^0.2.3", + "p-map": "^1.1.1", + "rxjs": "^5.4.2", + "stream-to-observable": "^0.2.0", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr-update-renderer": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz", + "integrity": "sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^1.0.2", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr-update-renderer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr-update-renderer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr-update-renderer/node_modules/indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr-update-renderer/node_modules/log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "dependencies": { + "chalk": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr-update-renderer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/listr-verbose-renderer/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr-verbose-renderer/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr-verbose-renderer/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/listr/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr/node_modules/log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "dependencies": { + "chalk": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/listr/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" + }, + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "engines": { + "node": ">=4" + } + }, + "node_modules/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "node_modules/lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, + "node_modules/lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + }, + "node_modules/lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=" + }, + "node_modules/lodash._basetostring": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" + }, + "node_modules/lodash._basevalues": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" + }, + "node_modules/lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + }, + "node_modules/lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + }, + "node_modules/lodash._reescape": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" + }, + "node_modules/lodash._reevaluate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "node_modules/lodash._root": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + }, + "node_modules/lodash.chunk": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", + "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=" + }, + "node_modules/lodash.cond": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", + "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" + }, + "node_modules/lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", + "dependencies": { + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" + } + }, + "node_modules/lodash.escape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", + "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dependencies": { + "lodash._root": "^3.0.0" + } + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + }, + "node_modules/lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "node_modules/lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dependencies": { + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" + } + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "node_modules/lodash.restparam": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + }, + "node_modules/lodash.set": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", + "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, + "node_modules/lodash.template": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dependencies": { + "lodash._basecopy": "^3.0.0", + "lodash._basetostring": "^3.0.0", + "lodash._basevalues": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.restparam": "^3.0.0", + "lodash.templatesettings": "^3.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", + "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" + } + }, + "node_modules/log-driver": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz", + "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=", + "engines": { + "node": ">=0.8.6" + } + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-update": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", + "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", + "dev": true, + "dependencies": { + "ansi-escapes": "^1.0.0", + "cli-cursor": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + }, + "node_modules/longest": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", + "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/mailparser": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-0.6.2.tgz", + "integrity": "sha1-A8SGA5vfTfbNO2rcqqxBB9/bwGg=", + "dependencies": { + "encoding": "^0.1.12", + "mime": "^1.3.4", + "mimelib": "^0.3.0", + "uue": "^3.1.0" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/make-iterator/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", + "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "dependencies": { + "findup-sync": "^2.0.0", + "micromatch": "^3.0.4", + "resolve": "^1.4.0", + "stack-trace": "0.0.10" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/matchdep/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/matchdep/node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/matchdep/node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matchdep/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/matchdep/node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memoizee": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", + "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.45", + "es6-weak-map": "^2.0.2", + "event-emitter": "^0.3.5", + "is-promise": "^2.1", + "lru-queue": "0.1", + "next-tick": "1", + "timers-ext": "^0.1.5" + } + }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, + "node_modules/merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==" + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "node_modules/method-override": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-2.3.9.tgz", + "integrity": "sha1-vRUfLONM8Bp2ykAKuVwBKxAtj3E=", + "dependencies": { + "debug": "2.6.8", + "methods": "~1.1.2", + "parseurl": "~1.3.1", + "vary": "~1.1.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/method-override/node_modules/debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/method-override/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dependencies": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/migrate": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/migrate/-/migrate-1.6.2.tgz", + "integrity": "sha512-XAFab+ArPTo9BHzmihKjsZ5THKRryenA+lwob0R+ax0hLDs7YzJFJT5YZE3gtntZgzdgcuFLs82EJFB/Dssr+g==", + "dependencies": { + "chalk": "^1.1.3", + "commander": "^2.9.0", + "dateformat": "^2.0.0", + "dotenv": "^4.0.0", + "inherits": "^2.0.3", + "minimatch": "^3.0.3", + "mkdirp": "^0.5.1", + "slug": "^0.9.2" + }, + "bin": { + "migrate": "bin/migrate", + "migrate-create": "bin/migrate-create", + "migrate-down": "bin/migrate-down", + "migrate-init": "bin/migrate-init", + "migrate-list": "bin/migrate-list", + "migrate-up": "bin/migrate-up" + }, + "engines": { + "node": ">= 0.4.x" + } + }, + "node_modules/migrate/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/migrate/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/migrate/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dependencies": { + "mime-db": "~1.38.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimelib": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.3.1.tgz", + "integrity": "sha1-eHrdJBXYJ6yzr27EvKHqlZZBiFM=", + "dependencies": { + "addressparser": "~1.0.1", + "encoding": "~0.1.12" + } + }, + "node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dependencies": { + "dom-walk": "^0.1.0" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mkdirp/node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "node_modules/mocha": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.0.tgz", + "integrity": "sha512-pIU2PJjrPYvYRqVpjXzj76qltO9uBYI7woYAMoxbSefsa+vqAfptjoeevd6bUgwD0mPIO+hv9f7ltvsNreL2PA==", + "dependencies": { + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.1", + "growl": "1.9.2", + "json3": "3.3.2", + "lodash.create": "3.1.1", + "mkdirp": "0.5.1", + "supports-color": "3.1.2" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 0.10.x", + "npm": ">= 1.4.x" + } + }, + "node_modules/mocha/node_modules/commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dependencies": { + "graceful-readlink": ">= 1.0.0" + }, + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.27", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.27.tgz", + "integrity": "sha512-EIKQs7h5sAsjhPCqN6ggx6cEbs94GK050254TIJySD1bzoM5JTYDwAU1IoVOeTOL6Gm27kYJ51/uuvq1kIlrbw==", + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mongodb": { + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.13.tgz", + "integrity": "sha512-sz2dhvBZQWf3LRNDhbd30KHVzdjZx9IKC0L+kSZ/gzYquCF5zPOgGqRz6sSCqYZtKP2ekB4nfLxhGtzGHnIKxA==", + "dependencies": { + "mongodb-core": "3.1.11", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mongodb-core": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.11.tgz", + "integrity": "sha512-rD2US2s5qk/ckbiiGFHeu+yKYDXdJ1G87F6CG3YdaZpzdOm5zpoAZd/EKbPmFO6cQZ+XVXBXBJ660sSI0gc6qg==", + "dependencies": { + "bson": "^1.1.0", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + }, + "optionalDependencies": { + "saslprep": "^1.0.0" + } + }, + "node_modules/mongoose": { + "version": "4.11.10", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-4.11.10.tgz", + "integrity": "sha512-+D+sS0aU1asnVhHCZnR9PHnaeJqcN+E9v3vMApbru8KRMbHek06njMnZ7EPLjQffwwXm/wnFVQ8OeF9EfOp9pA==", + "dependencies": { + "async": "2.1.4", + "bson": "~1.0.4", + "hooks-fixed": "2.0.0", + "kareem": "1.5.0", + "mongodb": "2.2.31", + "mpath": "0.3.0", + "mpromise": "0.5.5", + "mquery": "2.3.1", + "ms": "2.0.0", + "muri": "1.2.2", + "regexp-clone": "0.0.1", + "sliced": "1.0.1" + }, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/mongoose-slug-generator": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mongoose-slug-generator/-/mongoose-slug-generator-1.0.4.tgz", + "integrity": "sha1-pTZPLUIDeDRywjXDAtNaobINU+s=", + "dependencies": { + "async": "^1.5.0", + "shortid": "^2.2.4", + "speakingurl": "^7.0.0" + }, + "engines": { + "node": ">= 0.12.7" + } + }, + "node_modules/mongoose-slug-generator/node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "node_modules/mongoose-unique-validator": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mongoose-unique-validator/-/mongoose-unique-validator-2.0.2.tgz", + "integrity": "sha512-gbKFiEzWQi8wZvZFeeEkx4nCV1qWaeRoQBNm+672+h54/0u/Y8rSdNubScn/1H2ScCPO55asDow+OXq67RQDmg==", + "dependencies": { + "lodash.foreach": "^4.1.0", + "lodash.get": "^4.0.2" + } + }, + "node_modules/mongoose/node_modules/async": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz", + "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=", + "dependencies": { + "lodash": "^4.14.0" + } + }, + "node_modules/mongoose/node_modules/bson": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", + "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==", + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/mongoose/node_modules/mongodb": { + "version": "2.2.31", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.31.tgz", + "integrity": "sha1-GUBEXGYeGSF7s7+CRdmFSq71SNs=", + "dependencies": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.15", + "readable-stream": "2.2.7" + }, + "engines": { + "node": ">=0.10.3" + } + }, + "node_modules/mongoose/node_modules/mongodb-core": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.15.tgz", + "integrity": "sha1-hB9TuH//9MdFgYnDXIroJ+EWl2Q=", + "dependencies": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/mongoose/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "node_modules/mongoose/node_modules/readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "dependencies": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/mongoose/node_modules/string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "dependencies": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/mpath": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.3.0.tgz", + "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q=" + }, + "node_modules/mpromise": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mpromise/-/mpromise-0.5.5.tgz", + "integrity": "sha1-9bJCWddjrMIlewoMjG2Gb9UXMuY=" + }, + "node_modules/mquery": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-2.3.1.tgz", + "integrity": "sha1-mrNnSXFIAP8LtTpoHOS8TV8HyHs=", + "dependencies": { + "bluebird": "2.10.2", + "debug": "2.6.8", + "regexp-clone": "0.0.1", + "sliced": "0.0.5" + } + }, + "node_modules/mquery/node_modules/bluebird": { + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.10.2.tgz", + "integrity": "sha1-AkpVFylTCIV/FPkfEQb8O1VfRGs=" + }, + "node_modules/mquery/node_modules/debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/mquery/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/mquery/node_modules/sliced": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", + "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=" + }, + "node_modules/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==" + }, + "node_modules/multer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.1.tgz", + "integrity": "sha512-zzOLNRxzszwd+61JFuAo0fxdQfvku12aNJgnla0AQ+hHxFmfc/B7jBVuPr5Rmvu46Jze/iJrFpSOsD7afO8SDw==", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dependencies": { + "duplexer2": "0.0.2" + } + }, + "node_modules/muri": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/muri/-/muri-1.2.2.tgz", + "integrity": "sha1-YxmBMmUNsIoEzHnM0A3Tia/SYxw=" + }, + "node_modules/mute-stdout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/mute-stream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.6.tgz", + "integrity": "sha1-SJYrGeFp/R38JAs/HnMXYnu8R9s=" + }, + "node_modules/nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, + "node_modules/nanoid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.0.1.tgz", + "integrity": "sha512-k1u2uemjIGsn25zmujKnotgniC/gxQ9sdegdezeDiKdkDW56THUMqlz3urndKCXJxA6yPzSZbXx/QCMe/pxqsA==" + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nanomatch/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natives": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", + "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, + "node_modules/negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" + }, + "node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node_modules/nise": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.10.tgz", + "integrity": "sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA==", + "dev": true, + "dependencies": { + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nise/node_modules/@sinonjs/formatio": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", + "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "node_modules/nise/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/nocache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", + "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/nodemon": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.6.tgz", + "integrity": "sha512-4I3YDSKXg6ltYpcnZeHompqac4E6JeAMpGm8tJnB9Y3T0ehasLa4139dJOcCrB93HHrUMsCrKtoAlXTqT5n4AQ==", + "hasInstallScript": true, + "dependencies": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/nodemon/node_modules/binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/nodemon/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nodemon/node_modules/chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/nodemon/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/nodemon/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nodemon/node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "deprecated": "Please update to v 2.2.x", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nodemon/node_modules/glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/nodemon/node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nodemon/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nodemon/node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nodemon/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/nodemon/node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nodemon/node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/nodemon/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dependencies": { + "once": "^1.3.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/npm-path": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", + "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", + "dev": true, + "dependencies": { + "which": "^1.2.10" + }, + "bin": { + "npm-path": "bin/npm-path" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", + "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", + "dev": true, + "dependencies": { + "commander": "^2.9.0", + "npm-path": "^2.0.2", + "which": "^1.2.10" + }, + "bin": { + "npm-which": "bin/npm-which.js" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, + "node_modules/oauth": { + "version": "0.9.15", + "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", + "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" + }, + "node_modules/oauth-1.0a": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-2.2.6.tgz", + "integrity": "sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==" + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-visit/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.defaults/node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.defaults/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dependencies": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.map/node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dependencies": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.reduce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", + "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "dependencies": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.reduce/node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ono": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/ono/-/ono-4.0.11.tgz", + "integrity": "sha512-jQ31cORBFE6td25deYeD80wxKBMj+zBmHTrVxnc6CKhx8gho6ipmWM5zj/oeoqioZ99yqBls9Z/9Nss7J26G2g==", + "dependencies": { + "format-util": "^1.0.3" + } + }, + "node_modules/optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", + "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", + "dev": true, + "dependencies": { + "chalk": "^1.1.1", + "cli-cursor": "^1.0.2", + "cli-spinners": "^0.1.2", + "object-assign": "^4.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/orchestrator": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", + "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", + "dependencies": { + "end-of-stream": "~0.1.5", + "sequencify": "~0.0.7", + "stream-consume": "~0.1.0" + } + }, + "node_modules/ordered-read-streams": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", + "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=" + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-shim": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", + "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/output-file-sync": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", + "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", + "dependencies": { + "graceful-fs": "^4.1.4", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.0" + } + }, + "node_modules/p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "engines": { + "node": ">=4" + } + }, + "node_modules/package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dependencies": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/pad-right": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", + "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=", + "dependencies": { + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/page-metadata-parser": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/page-metadata-parser/-/page-metadata-parser-1.1.4.tgz", + "integrity": "sha512-TbPNw7GddbHs4c2DyYinFvh51BVsaMfdrweeylzGlg8qeuzALGxq2NF+6jbmeKc7DnU2BZRDOuWNnEjDwUSqRQ==" + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dependencies": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" + }, + "node_modules/parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "dependencies": { + "better-assert": "~1.0.0" + } + }, + "node_modules/parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "dependencies": { + "better-assert": "~1.0.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/passport": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", + "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-facebook-token": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/passport-facebook-token/-/passport-facebook-token-3.3.0.tgz", + "integrity": "sha1-dATKb903kOEQYMxgxWKyHw0Ege4=", + "dependencies": { + "passport-oauth": "1.0.0" + } + }, + "node_modules/passport-oauth": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-oauth/-/passport-oauth-1.0.0.tgz", + "integrity": "sha1-kK/2M4dUDwIImvKM2tOep/gNd98=", + "dependencies": { + "passport-oauth1": "1.x.x", + "passport-oauth2": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-oauth1": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.1.0.tgz", + "integrity": "sha1-p96YiiEfnPRoc3cTDqdN8ycwyRg=", + "dependencies": { + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "utils-merge": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-oauth2": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz", + "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==", + "dependencies": { + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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=" + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "engines": { + "node": "*" + } + }, + "node_modules/pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "engines": { + "node": ">=4" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pluralize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz", + "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=" + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "engines": { + "node": ">=4" + } + }, + "node_modules/preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pretty-format": { + "version": "21.2.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz", + "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "node_modules/psl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + }, + "node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pump/node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "dependencies": { + "escape-goat": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/qs-mongodb": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/qs-mongodb/-/qs-mongodb-0.1.0.tgz", + "integrity": "sha1-n+EaJ+F3eEjxBLNN69bj2hPLiFs=", + "dependencies": { + "qs": "~2.3.3" + } + }, + "node_modules/qs-mongodb/node_modules/qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=" + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dependencies": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randomatic/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randomstring": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/randomstring/-/randomstring-1.1.5.tgz", + "integrity": "sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM=", + "dependencies": { + "array-uniq": "1.0.2" + }, + "bin": { + "randomstring": "bin/randomstring" + }, + "engines": { + "node": "*" + } + }, + "node_modules/randomstring/node_modules/array-uniq": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz", + "integrity": "sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.2.0.tgz", + "integrity": "sha1-mUl2z2pQlqQRYoQEkvC9xdbn+5Y=", + "dependencies": { + "bytes": "2.4.0", + "iconv-lite": "0.4.15", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/readdirp/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readdirp/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/recaptcha2": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/recaptcha2/-/recaptcha2-1.3.3.tgz", + "integrity": "sha512-HgpvAmukTQW1UyZxM7PT/yLFayAN6rjTvYH13z/Ci69KfcOtv3BskRGBu7in+npzUG9XSxYAfRDtn6+p6p7tAw==", + "dependencies": { + "request": "2.x" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/recursive-iterator/-/recursive-iterator-2.0.3.tgz", + "integrity": "sha1-0ODSx+eoMQnXMJHPBD/FCeWnbcM=" + }, + "node_modules/reduce": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce/-/reduce-1.0.2.tgz", + "integrity": "sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ==", + "dependencies": { + "object-keys": "^1.1.0" + } + }, + "node_modules/referrer-policy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", + "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + }, + "node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "node_modules/regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dependencies": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "node_modules/regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dependencies": { + "is-equal-shallow": "^0.1.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp-clone": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz", + "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk=" + }, + "node_modules/regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dependencies": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "node_modules/registry-auth-token": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dependencies": { + "rc": "^1.2.8" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" + }, + "node_modules/regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dependencies": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dependencies": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "node_modules/repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/replace-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", + "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", + "dependencies": { + "homedir-polyfill": "^1.0.1", + "is-absolute": "^1.0.0", + "remove-trailing-separator": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "dependencies": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "dependencies": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "node_modules/require_optional/node_modules/resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "node_modules/require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dependencies": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, + "node_modules/resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/resolve-dir": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", + "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", + "dependencies": { + "expand-tilde": "^1.2.2", + "global-modules": "^0.2.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dependencies": { + "value-or-function": "^3.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/restore-cursor": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", + "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "dependencies": { + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "engines": { + "node": ">=0.12" + } + }, + "node_modules/right-pad": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", + "integrity": "sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dependencies": { + "is-promise": "^2.1.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-sequence": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.1.0.tgz", + "integrity": "sha1-FJ2gElFvIdz3nbbcmaKpVgNjGyE=", + "dependencies": { + "chalk": "^1.1.3", + "gulp-util": "^3.0.8" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/run-sequence/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/run-sequence/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=" + }, + "node_modules/rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + }, + "node_modules/rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dependencies": { + "rx-lite": "*" + } + }, + "node_modules/rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "dev": true, + "dependencies": { + "symbol-observable": "1.0.1" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/rxjs/node_modules/symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "node_modules/saslprep": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.2.tgz", + "integrity": "sha512-4cDsYuAjXssUSjxHKRe4DTZC0agDwsCqcMqtJAQPzC74nJ7LfAJflAtC1Zed5hMzEQKj82d3tuzqdGNRsLJ4Gw==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + }, + "node_modules/saxes": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-4.0.2.tgz", + "integrity": "sha512-EZOTeQ4bgkOaGCDaTKux+LaRNcLNbdbvMH7R3/yjEEULPEmqvkFbFub6DJhJTub2iGMT93CfpZ5LTdKZmAbVeQ==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dependencies": { + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/semver-diff/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-greatest-satisfied-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", + "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "dependencies": { + "sver-compat": "^1.5.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/semver-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz", + "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dependencies": { + "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.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/send/node_modules/http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/send/node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "node_modules/sendgrid": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/sendgrid/-/sendgrid-5.2.3.tgz", + "integrity": "sha512-FD7oR9TbJFUew1p0Vw9JX0wBetDyq634LzylSXz4n9+hwaf+6a9dNloZl8CcjpsX4NuEc3HJanTN4GjDwNyi4A==", + "dependencies": { + "async.ensureasync": "^0.5.2", + "async.queue": "^0.5.2", + "bottleneck": "^1.12.0", + "debug": "^2.2.0", + "lodash.chunk": "^4.2.0", + "mailparser": "^0.6.1", + "sendgrid-rest": "^2.3.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/sendgrid-rest": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/sendgrid-rest/-/sendgrid-rest-2.4.0.tgz", + "integrity": "sha512-3VRHhTnln17jPQNzBjEHO6u2Y7kLlhVnOvX0aGjr7yRVZpq5LXo0ilAFMsaHUfKVH+jFdCrHMAVLOAdtu6wLJA==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/sendgrid/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/sendgrid/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/sequencify": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", + "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shelljs": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.6.tgz", + "integrity": "sha1-N5zM+1a5HIYB5HkzVutTgpJN6a0=", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "iojs": "*", + "node": ">=0.11.0" + } + }, + "node_modules/shortid": { + "version": "2.2.14", + "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.14.tgz", + "integrity": "sha512-4UnZgr9gDdA1kaKj/38IiudfC3KHKhDc1zi/HSxd9FQDR0VLwH3/y79tZJLsVYPsJgIjeHjqIWaWVRJUj9qZOQ==", + "dependencies": { + "nanoid": "^2.0.0" + } + }, + "node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "node_modules/sinon": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", + "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", + "dev": true, + "dependencies": { + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.1.0", + "lodash.get": "^4.4.2", + "lolex": "^2.2.0", + "nise": "^1.2.0", + "supports-color": "^5.1.0", + "type-detect": "^4.0.5" + } + }, + "node_modules/sinon-mongoose": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/sinon-mongoose/-/sinon-mongoose-2.2.1.tgz", + "integrity": "sha512-Z+E3924Bvy+Gre9bKT3IyQuXOtw6ZI+4VoC49X2pQoOf+wrC0yCi0jd+FtVD+xsRvSKcR+GscPbFaGm1ZkPNDg==", + "dev": true + }, + "node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/slice-ansi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "engines": { + "node": ">=4" + } + }, + "node_modules/sliced": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", + "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" + }, + "node_modules/slug": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/slug/-/slug-0.9.4.tgz", + "integrity": "sha512-3YHq0TeJ4+AIFbJm+4UWSQs5A1mmeWOTQqydW3OoPmQfNKxlO96NDRTIrp+TBkmvEsEFrd+Z/LXw8OD/6OlZ5g==", + "dependencies": { + "unicode": ">= 0.3.1" + }, + "bin": { + "slug": "bin/slug.js" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/sntp": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", + "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "dependencies": { + "hoek": "2.x.x" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/socket.io": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", + "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "dependencies": { + "debug": "~4.1.0", + "engine.io": "~3.4.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.3.0", + "socket.io-parser": "~3.4.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" + }, + "node_modules/socket.io-client": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", + "dependencies": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/socket.io-client/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "node_modules/socket.io-client/node_modules/socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "dependencies": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "node_modules/socket.io-client/node_modules/socket.io-parser/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/socket.io-client/node_modules/socket.io-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/socket.io-parser": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.0.tgz", + "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==", + "dependencies": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/socket.io-parser/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dependencies": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dependencies": { + "source-map": "^0.5.6" + } + }, + "node_modules/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" + }, + "node_modules/sparkles": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, + "node_modules/spawn-sync": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", + "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", + "dependencies": { + "concat-stream": "^1.4.7", + "os-shim": "^0.1.2" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==" + }, + "node_modules/speakingurl": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-7.0.0.tgz", + "integrity": "sha1-Cjkoc6+DutWUVlzj3LQzLVGHqws=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "engines": { + "node": "*" + } + }, + "node_modules/staged-git-files": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-1.0.0.tgz", + "integrity": "sha1-zbhHg3wfzFLAioctSIPMCHdmioA=", + "dev": true + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stream-consume": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", + "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==" + }, + "node_modules/stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==" + }, + "node_modules/stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + }, + "node_modules/stream-to-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.2.0.tgz", + "integrity": "sha1-WdbqOT2HwsDdrBCqDVYbxrpvDhA=", + "dev": true, + "dependencies": { + "any-observable": "^0.2.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "dependencies": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stripe": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-5.10.0.tgz", + "integrity": "sha512-AUDmXfNAAY/oOfW87HPO4bDzNWJp8iQd0blVWwwEgPxO1DmEC//foI0C9rhr2ZNsuF6kLypPfNtGB9Uf+RCQzQ==", + "dependencies": { + "lodash.isplainobject": "^4.0.6", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "dependencies": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/supertest": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-3.0.0.tgz", + "integrity": "sha1-jUu2j9GDDuBwM7HFpamkAhyWUpY=", + "dependencies": { + "methods": "~1.1.2", + "superagent": "^3.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/supertest-as-promised": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/supertest-as-promised/-/supertest-as-promised-4.0.2.tgz", + "integrity": "sha1-BGTyvSVlaNSlm86EJpwFSPaHnxo=", + "dependencies": { + "bluebird": "^3.3.1", + "methods": "^1.1.1" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sver-compat": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", + "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", + "dependencies": { + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/swagger-jsdoc": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-1.10.3.tgz", + "integrity": "sha512-ol8QBX8wxm4sik+W0uiMcLNxdB+cKhtsXy3LMbnNe8KabdpMH9wRFQBdP7LtrCR6kx9zjWvqMTLpnUv0zJjFlg==", + "dependencies": { + "chokidar": "^2.0.3", + "commander": "^2.11.0", + "doctrine": "^2.0.0", + "glob": "^7.1.2", + "js-yaml": "^3.8.4", + "recursive-iterator": "^2.0.3", + "swagger-parser": "^3.4.1" + }, + "bin": { + "swagger-jsdoc": "bin/swagger-jsdoc.js" + } + }, + "node_modules/swagger-jsdoc/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/swagger-jsdoc/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/chokidar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz", + "integrity": "sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==", + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.0" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/swagger-jsdoc/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/is-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/swagger-jsdoc/node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-jsdoc/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/swagger-jsdoc/node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/swagger-methods": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/swagger-methods/-/swagger-methods-1.0.8.tgz", + "integrity": "sha512-G6baCwuHA+C5jf4FNOrosE4XlmGsdjbOjdBK4yuiDDj/ro9uR4Srj3OR84oQMT8F3qKp00tYNv0YN730oTHPZA==" + }, + "node_modules/swagger-node-express": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/swagger-node-express/-/swagger-node-express-2.1.3.tgz", + "integrity": "sha1-Sx/ul24RKE0nZXWRGYCyJY43nas=", + "dev": true, + "dependencies": { + "lodash": "1.3.1" + }, + "engines": { + "node": ">= 0.8.x" + } + }, + "node_modules/swagger-node-express/node_modules/lodash": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.3.1.tgz", + "integrity": "sha1-pGY7U2hriV/wdOK6UE37dqjit3A=", + "dev": true, + "engines": [ + "node", + "rhino" + ] + }, + "node_modules/swagger-parser": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-3.4.2.tgz", + "integrity": "sha512-himpIkA50AjTvrgtz0PPbzwWoTjj3F3ye/y1PcW/514YEp1A3IhAcJFkkEu7b1zHnSIthnzxC8aTy+XZG0D+iA==", + "dependencies": { + "call-me-maybe": "^1.0.1", + "debug": "^3.0.0", + "es6-promise": "^4.1.1", + "json-schema-ref-parser": "^1.4.1", + "ono": "^4.0.2", + "swagger-methods": "^1.0.0", + "swagger-schema-official": "2.0.0-bab6bed", + "z-schema": "^3.16.1" + } + }, + "node_modules/swagger-parser/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/swagger-parser/node_modules/es6-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" + }, + "node_modules/swagger-schema-official": { + "version": "2.0.0-bab6bed", + "resolved": "https://registry.npmjs.org/swagger-schema-official/-/swagger-schema-official-2.0.0-bab6bed.tgz", + "integrity": "sha1-cAcEaNbSl3ylI3suUZyn0Gouo/0=" + }, + "node_modules/symbol-observable": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", + "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, + "node_modules/table": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "dependencies": { + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "dependencies": { + "os-homedir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, + "node_modules/tmp": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", + "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", + "dependencies": { + "os-tmpdir": "~1.0.1" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, + "node_modules/to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dependencies": { + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/touch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", + "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dependencies": { + "nopt": "~1.0.10" + }, + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dependencies": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "node_modules/twitter-lite": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/twitter-lite/-/twitter-lite-0.13.0.tgz", + "integrity": "sha512-UQxOqiZIx6BbWMNXrFhDThHf0RYuAWe02+0wHbsww61iIPeJdaakM+HJJlf8QKzIyu8q6JCZ4K9vpd55sg0V7g==", + "dependencies": { + "cross-fetch": "^3.0.0", + "oauth-1.0a": "^2.2.4" + } + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/type-is": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", + "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.18" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/uglify-js": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.8.0.tgz", + "integrity": "sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ==", + "optional": true, + "dependencies": { + "commander": "~2.20.3", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-js/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "optional": true + }, + "node_modules/uglify-js/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undefsafe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "dependencies": { + "debug": "^2.2.0" + } + }, + "node_modules/undefsafe/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/undefsafe/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/undertaker": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", + "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", + "dependencies": { + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "bach": "^1.0.0", + "collection-map": "^1.0.0", + "es6-weak-map": "^2.0.1", + "last-run": "^1.1.0", + "object.defaults": "^1.0.0", + "object.reduce": "^1.0.0", + "undertaker-registry": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/undertaker-registry": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/unicode": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/unicode/-/unicode-12.1.0.tgz", + "integrity": "sha512-Ty6+Ew21DiYTWLYtd05RF/X4c1ekOvOgANyHbBj0h3MaXpfaGr2Rdmc0hMFuGQLyPLb9cU4ArNxl0bTF5HSzXw==", + "engines": { + "node": ">= 0.8.x" + } + }, + "node_modules/unicons": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/unicons/-/unicons-0.0.3.tgz", + "integrity": "sha1-bmp6Gm6uuwHKPYsSrZaHJ56rpSQ=" + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unique-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", + "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=" + }, + "node_modules/unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "dependencies": { + "crypto-random-string": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-notifier": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "dependencies": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/yeoman/update-notifier?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/update-notifier/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "node_modules/update-notifier/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/update-notifier/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/update-notifier/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/update-notifier/node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/update-notifier/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "node_modules/url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/user-home": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", + "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", + "bin": { + "user-home": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uue": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/uue/-/uue-3.1.2.tgz", + "integrity": "sha512-axKLXVqwtdI/czrjG0X8hyV1KLgeWx8F4KvSbvVCnS+RUvsQMGRjx0kfuZDXXqj0LYvVJmx3B9kWlKtEdRrJLg==", + "dependencies": { + "escape-string-regexp": "~1.0.5", + "extend": "~3.0.0" + } + }, + "node_modules/uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8flags": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", + "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", + "dependencies": { + "user-home": "^1.1.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/validate-commit-msg": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/validate-commit-msg/-/validate-commit-msg-2.14.0.tgz", + "integrity": "sha1-5Tg2kQEsuycNzAvCpO/+vhSJDqw=", + "dependencies": { + "conventional-commit-types": "^2.0.0", + "find-parent-dir": "^0.3.0", + "findup": "0.1.5", + "semver-regex": "1.0.0" + }, + "bin": { + "validate-commit-msg": "lib/cli.js" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vinyl": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", + "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dependencies": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/vinyl-fs": { + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", + "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", + "dependencies": { + "defaults": "^1.0.0", + "glob-stream": "^3.1.5", + "glob-watcher": "^0.0.6", + "graceful-fs": "^3.0.0", + "mkdirp": "^0.5.0", + "strip-bom": "^1.0.0", + "through2": "^0.6.1", + "vinyl": "^0.4.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-fs/node_modules/clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "engines": { + "node": "*" + } + }, + "node_modules/vinyl-fs/node_modules/graceful-fs": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", + "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", + "dependencies": { + "natives": "^1.1.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/vinyl-fs/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/vinyl-fs/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/vinyl-fs/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/vinyl-fs/node_modules/strip-bom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", + "dependencies": { + "first-chunk-stream": "^1.0.0", + "is-utf8": "^0.2.0" + }, + "bin": { + "strip-bom": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vinyl-fs/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/vinyl-fs/node_modules/vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dependencies": { + "clone": "^0.2.0", + "clone-stats": "^0.0.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dependencies": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/vinyl-sourcemap/node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + }, + "node_modules/vinyl-sourcemap/node_modules/replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "dependencies": { + "source-map": "^0.5.1" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dependencies": { + "browser-process-hrtime": "^0.1.2" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "node_modules/whatwg-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.0.0.tgz", + "integrity": "sha512-41ou2Dugpij8/LPO5Pq64K5q++MnRCBpEHvQr26/mArEKTkCV5aoXIqyhuYtE0pkqScXwhf2JP57rkRTYM29lQ==", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.0", + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/widest-line/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/widest-line/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/winston": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/winston/-/winston-2.3.1.tgz", + "integrity": "sha1-C0hCDZeMAYBM8CMLZIhhWYIloRk=", + "dependencies": { + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/winston/node_modules/async": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", + "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=" + }, + "node_modules/winston/node_modules/colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", + "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", + "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==", + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/x-xss-protection": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", + "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + }, + "node_modules/xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" + } + }, + "node_modules/xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "node_modules/xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "node_modules/yargs": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz", + "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==", + "dependencies": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "5.0.0-security.0" + } + }, + "node_modules/yargs-parser": { + "version": "5.0.0-security.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz", + "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==", + "dependencies": { + "camelcase": "^3.0.0", + "object.assign": "^4.1.0" + } + }, + "node_modules/yargs/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yargs/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, + "node_modules/z-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.25.1.tgz", + "integrity": "sha512-7tDlwhrBG+oYFdXNOjILSurpfQyuVgkRe3hB2q8TEssamDHB7BbLWYkYO98nTn0FibfdFroFKDjndbgufAgS/Q==", + "dependencies": { + "commander": "^2.7.1", + "core-js": "^2.5.7", + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^10.0.0" + }, + "bin": { + "z-schema": "bin/z-schema" + } + } + }, + "dependencies": { + "@gulp-sourcemaps/identity-map": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", + "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==", + "requires": { + "acorn": "^5.0.3", + "css": "^2.2.1", + "normalize-path": "^2.1.1", + "source-map": "^0.6.0", + "through2": "^2.0.3" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "requires": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + } + }, + "@sendgrid/client": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-6.3.0.tgz", + "integrity": "sha512-fTy8vRpA9Whtf8ULQr/0vkSZaQvGQ97rY5N5PrevKRtugJMsJqFMKO0pwzEWeqITSg71aMMTj57QTgw3SjZvnQ==", + "requires": { + "@sendgrid/helpers": "^6.3.0", + "@types/request": "^2.0.3", + "request": "^2.81.0" + } + }, + "@sendgrid/helpers": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-6.3.0.tgz", + "integrity": "sha512-uTFcmhCDFg/2Uhz+z/cLwyLHH0UsblG49hKwdR7nKbWsGKWv4js7W32FlPdXqy2C/plTJ20vcPLgKM1m3F/MjQ==", + "requires": { + "chalk": "^2.0.1", + "deepmerge": "^2.1.1" + } + }, + "@sendgrid/mail": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-6.3.1.tgz", + "integrity": "sha512-5zIeAV9iU+0hQkrOQ/D4RB2MfpK+lNbOortIfQdCh95aMDF/TRc9WB8FGNhmQrx9YMuJTms5eiBklF0Fi/dbVg==", + "requires": { + "@sendgrid/client": "^6.3.0", + "@sendgrid/helpers": "^6.3.0" + } + }, + "@sentry/apm": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/apm/-/apm-5.17.0.tgz", + "integrity": "sha512-raJcPa04TP8mVocSTHe0PdULpRWhw0NaLq9Rk8KCTFBJvLsgzY2krph5/LgEfBBX78vWt70FrwSw+DdIfYIJ6g==", + "requires": { + "@sentry/browser": "5.17.0", + "@sentry/hub": "5.17.0", + "@sentry/minimal": "5.17.0", + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "tslib": "^1.9.3" + } + }, + "@sentry/browser": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.17.0.tgz", + "integrity": "sha512-++pXpCHtdek1cRUwVeLvlxUJ2w1s+eiC9qN1N+7+HdAjHpBz2/tA1sKBCqwwVQZ490Cf2GLll9Ao7fuPPmveRQ==", + "requires": { + "@sentry/core": "5.17.0", + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "tslib": "^1.9.3" + } + }, + "@sentry/core": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.17.0.tgz", + "integrity": "sha512-Kfx4rGKDC7V1YJjTGJXyl12VVHxM8Cjpu61YOyF8kXoXXg9u06C3n0G1dmfzLQERKXasUVMtXRBdKx/OjYpl1g==", + "requires": { + "@sentry/hub": "5.17.0", + "@sentry/minimal": "5.17.0", + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "tslib": "^1.9.3" + } + }, + "@sentry/hub": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.17.0.tgz", + "integrity": "sha512-lyUbEmshwaMYdAzy4iwgizgvKODVVloB2trnefpq90AuWCdvzcxMLIGULx1ou+KohccqdNorYICKWeuRscKq5A==", + "requires": { + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "tslib": "^1.9.3" + } + }, + "@sentry/minimal": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.17.0.tgz", + "integrity": "sha512-v8xfkySXKrliZO6er6evlVe/ViUcqN0O8BhGyauK28Mf+KnKEOs5W6oWbt4qCDIttw9ynKIYyRrkAl/9oUR76A==", + "requires": { + "@sentry/hub": "5.17.0", + "@sentry/types": "5.17.0", + "tslib": "^1.9.3" + } + }, + "@sentry/node": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.17.0.tgz", + "integrity": "sha512-gaM+LNjQc7Wm+RG4f7KGZ/+An8RQ9/8CkJDB/DP4qwufsaIrcg1dZa6KeAUnh3KaXZ+ZuPji+agCIV/AQU4x8g==", + "requires": { + "@sentry/apm": "5.17.0", + "@sentry/core": "5.17.0", + "@sentry/hub": "5.17.0", + "@sentry/types": "5.17.0", + "@sentry/utils": "5.17.0", + "cookie": "^0.3.1", + "https-proxy-agent": "^4.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + } + }, + "@sentry/types": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.17.0.tgz", + "integrity": "sha512-1z8EXzvg8GcsBNnSXgB5/G7mz2PwmMt9mjOrVG1jhtSGH1c7WvB32F5boqoMcjIJmy5MrBGaaXwrF/RRJrwUQg==" + }, + "@sentry/utils": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.17.0.tgz", + "integrity": "sha512-qn8WgZcSkV/rx0ezp9q/xFjP7aMaYZO1/JYLXV4o6pYrQ9tvMmmwAZT39FpJunhhbkR36WNEuRB9C2K250cb/A==", + "requires": { + "@sentry/types": "5.17.0", + "tslib": "^1.9.3" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==" + }, + "@sinonjs/commons": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", + "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.0.tgz", + "integrity": "sha512-beHeJM/RRAaLLsMJhsCvHK31rIqZuobfPLa/80yGH5hnD8PV1hyh9xJBJNFfNmO7yWqm+zomijHsXpI6iTQJfQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash": "^4.17.11" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/caseless": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", + "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + }, + "@types/form-data": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", + "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/http-proxy": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz", + "integrity": "sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.4.tgz", + "integrity": "sha512-02tIL+QIi/RW4E5xILdoAMjeJ9kYq5t5S2vciUdFPXv/ikFTb0zK8q9vXkg4+WAJuYXGiVT1H28AkD2C+IkXVw==" + }, + "@types/request": { + "version": "2.48.1", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz", + "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==", + "requires": { + "@types/caseless": "*", + "@types/form-data": "*", + "@types/node": "*", + "@types/tough-cookie": "*" + } + }, + "@types/tough-cookie": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", + "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" + }, + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" + }, + "abbrev": { + "version": "1.1.1", + "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": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==" + }, + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" + } + } + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + } + } + }, + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" + }, + "addressparser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", + "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=" + }, + "after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" + }, + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==" + }, + "agentkeepalive": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-2.2.0.tgz", + "integrity": "sha1-xdG9SxKQCPEWPyNvhuX66iAm4u8=" + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", + "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==" + }, + "algoliasearch": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-3.35.1.tgz", + "integrity": "sha512-K4yKVhaHkXfJ/xcUnil04xiSrB8B8yHZoFEhWNpXg23eiCnqvTZw1tn/SqvdsANlYHLJlKl0qi3I/Q2Sqo7LwQ==", + "requires": { + "agentkeepalive": "^2.2.0", + "debug": "^2.6.9", + "envify": "^4.0.0", + "es6-promise": "^4.1.0", + "events": "^1.1.0", + "foreach": "^2.0.5", + "global": "^4.3.2", + "inherits": "^2.0.1", + "isarray": "^2.0.1", + "load-script": "^1.0.0", + "object-keys": "^1.0.11", + "querystring-es3": "^0.2.1", + "reduce": "^1.0.1", + "semver": "^5.1.0", + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=" + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" + }, + "any-observable": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.2.0.tgz", + "integrity": "sha1-xnhwBYADV5AJCD9UrAq6+1wz0kI=", + "dev": true + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "app-root-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.1.0.tgz", + "integrity": "sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo=", + "dev": true + }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "requires": { + "buffer-equal": "^1.0.0" + } + }, + "append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" + }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "requires": { + "default-require-extensions": "^1.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "arr-filter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", + "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "requires": { + "make-iterator": "^1.0.0" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", + "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "requires": { + "make-iterator": "^1.0.0" + } + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=" + }, + "array-each": { + "version": "1.0.1", + "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-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, + "array-initial": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", + "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "requires": { + "array-slice": "^1.0.0", + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + } + } + }, + "array-last": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", + "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "requires": { + "is-number": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + } + } + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==" + }, + "array-sort": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", + "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "requires": { + "default-compare": "^1.0.0", + "get-value": "^2.0.6", + "kind-of": "^5.0.2" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "async": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.1.1.tgz", + "integrity": "sha512-X5Dj8hK1pJNC2Wzo2Rcp9FBVdJMGRR/S7V+lH46s8GVFhtbo5O4Le5GECCF/8PISVdkUA6mMPvgz7qTTD1rf1g==" + }, + "async-done": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", + "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.2", + "process-nextick-args": "^2.0.0", + "stream-exhaust": "^1.0.1" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + } + } + }, + "async-each": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.2.tgz", + "integrity": "sha512-6xrbvN0MOBKSJDdonmSSz2OwFSgxRaVtBDes26mj9KIGtDo+g9xosFRSC+i1gQh2oAN/tQ62AI/pGZGQjVOiRg==" + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" + }, + "async-settle": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", + "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "requires": { + "async-done": "^1.2.2" + } + }, + "async.ensureasync": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.ensureasync/-/async.ensureasync-0.5.2.tgz", + "integrity": "sha1-w8fkpOmzHZaHXVa4UEWYRG4eMF0=", + "requires": { + "async.util.ensureasync": "0.5.2" + } + }, + "async.queue": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.queue/-/async.queue-0.5.2.tgz", + "integrity": "sha1-jV2QgS4UgQZrwJBOjMFxKxfDvXw=", + "requires": { + "async.util.queue": "0.5.2" + } + }, + "async.util.arrayeach": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.arrayeach/-/async.util.arrayeach-0.5.2.tgz", + "integrity": "sha1-WMTpgCjVXWm/sFrrOvROClVagpw=" + }, + "async.util.ensureasync": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.ensureasync/-/async.util.ensureasync-0.5.2.tgz", + "integrity": "sha1-EJB/LL0GegYfma5tIuCM7TDbDWg=", + "requires": { + "async.util.restparam": "0.5.2", + "async.util.setimmediate": "0.5.2" + } + }, + "async.util.isarray": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz", + "integrity": "sha1-5i2sjyY29lh13PdSHC0k0N+yu98=" + }, + "async.util.map": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.map/-/async.util.map-0.5.2.tgz", + "integrity": "sha1-5YjvhuCzq18CfZevTWg10FXKadY=" + }, + "async.util.noop": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz", + "integrity": "sha1-vdYrl8sKo/YLWGrRSEaGmJdeWLk=" + }, + "async.util.onlyonce": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz", + "integrity": "sha1-uOb8AErckjFk154y8oE+5GXCT/I=" + }, + "async.util.queue": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.queue/-/async.util.queue-0.5.2.tgz", + "integrity": "sha1-V/Zavho83yc9MavSirlUJfgiLuU=", + "requires": { + "async.util.arrayeach": "0.5.2", + "async.util.isarray": "0.5.2", + "async.util.map": "0.5.2", + "async.util.noop": "0.5.2", + "async.util.onlyonce": "0.5.2", + "async.util.setimmediate": "0.5.2" + } + }, + "async.util.restparam": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz", + "integrity": "sha1-A+/r88Ane5ciDlJaunUPXgT8gM0=" + }, + "async.util.setimmediate": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/async.util.setimmediate/-/async.util.setimmediate-0.5.2.tgz", + "integrity": "sha1-KBLrq/KlgCd1jUvHeT0cz68QJV8=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "aws-sdk": { + "version": "2.425.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.425.0.tgz", + "integrity": "sha512-SM2qZJPlZUKVzSSqNuCvONOhJ2kcFvU+hAwutjQeje2VKpSAbUbFCFWl6cki2FjiyGZYEPfl0Q+3ANJO8gx9BA==", + "requires": { + "buffer": "4.9.1", + "events": "1.1.1", + "ieee754": "1.1.8", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "babel-cli": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz", + "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", + "requires": { + "babel-core": "^6.26.0", + "babel-polyfill": "^6.26.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "chokidar": "^1.6.1", + "commander": "^2.11.0", + "convert-source-map": "^1.5.0", + "fs-readdir-recursive": "^1.0.0", + "glob": "^7.1.2", + "lodash": "^4.17.4", + "output-file-sync": "^1.1.2", + "path-is-absolute": "^1.0.1", + "slash": "^1.0.0", + "source-map": "^0.5.6", + "v8flags": "^2.1.1" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "babel-core": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", + "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.0", + "debug": "^2.6.8", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.7", + "slash": "^1.0.0", + "source-map": "^0.5.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "requires": { + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-add-module-exports": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-0.2.1.tgz", + "integrity": "sha1-mumh9KjcZ/DN7E9K7aHkOl/2XiU=" + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" + }, + "babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=" + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=" + }, + "babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=" + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=" + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=" + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" + }, + "babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "requires": { + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + } + } + }, + "babel-preset-es2015": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" + } + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" + } + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "requires": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" + }, + "bach": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", + "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "requires": { + "arr-filter": "^1.1.1", + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "array-each": "^1.0.0", + "array-initial": "^1.0.0", + "array-last": "^1.1.1", + "async-done": "^1.2.2", + "async-settle": "^1.0.0", + "now-and-later": "^2.0.0" + } + }, + "backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "base64-arraybuffer": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", + "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" + }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bcrypt-nodejs": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/bcrypt-nodejs/-/bcrypt-nodejs-0.0.3.tgz", + "integrity": "sha1-xgkX8m3CNWYVZsaBBhwwPCsohCs=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "beeper": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + }, + "better-assert": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", + "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "requires": { + "callsite": "1.0.0" + } + }, + "binary-extensions": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.0.tgz", + "integrity": "sha512-EgmjVLMn22z7eGGv3kcnHwSnJXmFHjISTY9E/S5lIcTD3Oxw05QTcBLNkJFzcb3cNueUdF/IN4U+d78V0zO8Hw==" + }, + "blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=" + }, + "body-parser": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.17.2.tgz", + "integrity": "sha1-+IkqvI+eYn1Crtr7yma/WrmRBO4=", + "requires": { + "bytes": "2.4.0", + "content-type": "~1.0.2", + "debug": "2.6.7", + "depd": "~1.1.0", + "http-errors": "~1.6.1", + "iconv-lite": "0.4.15", + "on-finished": "~2.3.0", + "qs": "6.4.0", + "raw-body": "~2.2.0", + "type-is": "~1.6.15" + }, + "dependencies": { + "debug": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.7.tgz", + "integrity": "sha1-krrR9tBbu2u6Isyoi80OyJTChh4=", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "qs": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", + "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + } + } + }, + "boom": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", + "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "requires": { + "hoek": "2.x.x" + } + }, + "bottleneck": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-1.16.0.tgz", + "integrity": "sha1-1s4TgIUnr8gLaQkvFWBmVeWyHxo=" + }, + "bowser": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.6.1.tgz", + "integrity": "sha512-hySGUuLhi0KetfxPZpuJOsjM0kRvCiCgPBygBkzGzJNsq/nbJmaO8QJc6xlWfeFFnMvtd/LeKkhDJGVrmVobUA==" + }, + "boxen": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz", + "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==", + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "cli-boxes": "^2.2.0", + "string-width": "^4.1.0", + "term-size": "^2.1.0", + "type-fest": "^0.8.1", + "widest-line": "^3.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=" + }, + "bson": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", + "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==" + }, + "buffer": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=" + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "bytes": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz", + "integrity": "sha1-fZcZb51br39pNeJZhVSe3SpsIzk=" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "requires": { + "os-homedir": "^1.0.1" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=" + }, + "caller-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", + "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "requires": { + "callsites": "^0.2.0" + } + }, + "callsite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", + "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" + }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", + "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", + "requires": { + "assertion-error": "^1.0.1", + "check-error": "^1.0.1", + "deep-eql": "^3.0.0", + "get-func-name": "^2.0.0", + "pathval": "^1.0.0", + "type-detect": "^4.0.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + } + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "circular-json": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==" + }, + "cli-cursor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", + "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "requires": { + "restore-cursor": "^1.0.1" + } + }, + "cli-spinners": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", + "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", + "dev": true + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + }, + "dependencies": { + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + } + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + }, + "cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", + "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "requires": { + "arr-map": "^2.0.2", + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "requires": { + "for-in": "^1.0.1" + } + } + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + }, + "commitizen": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/commitizen/-/commitizen-2.9.6.tgz", + "integrity": "sha1-wNAFNe8mTaf2Nzft/aQiiYP6IpE=", + "requires": { + "cachedir": "^1.1.0", + "chalk": "1.1.3", + "cz-conventional-changelog": "1.2.0", + "dedent": "0.6.0", + "detect-indent": "4.0.0", + "find-node-modules": "1.0.4", + "find-root": "1.0.0", + "fs-extra": "^1.0.0", + "glob": "7.1.1", + "inquirer": "1.2.3", + "lodash": "4.17.2", + "minimist": "1.2.0", + "path-exists": "2.1.0", + "shelljs": "0.7.6", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cz-conventional-changelog": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-1.2.0.tgz", + "integrity": "sha1-K8oElkyJGbI/P9aonvXmAIsxs/g=", + "requires": { + "conventional-commit-types": "^2.0.0", + "lodash.map": "^4.5.1", + "longest": "^1.0.1", + "pad-right": "^0.2.2", + "right-pad": "^1.0.1", + "word-wrap": "^1.0.3" + } + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.2.tgz", + "integrity": "sha1-NKMFW6vgTOQkZ7YH1wAHLH/2v0I=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + }, + "component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + }, + "compressible": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.16.tgz", + "integrity": "sha512-JQfEOdnI7dASwCuSPWIeVYwc/zMsu/+tRhoUvEfXz2gxOA2DNjmG5vhtFdBlhWPPGo+RdT9S3tgc/uH5qgDiiA==", + "requires": { + "mime-db": ">= 1.38.0 < 2" + } + }, + "compression": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.0.tgz", + "integrity": "sha1-AwyfGY8WQ6BX13anOOki2kNzAS0=", + "requires": { + "accepts": "~1.3.3", + "bytes": "2.5.0", + "compressible": "~2.0.10", + "debug": "2.6.8", + "on-headers": "~1.0.1", + "safe-buffer": "5.1.1", + "vary": "~1.1.1" + }, + "dependencies": { + "bytes": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz", + "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=" + }, + "debug": { + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-security-policy-builder": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz", + "integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==" + }, + "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==" + }, + "conventional-commit-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-2.2.0.tgz", + "integrity": "sha1-XblXOdbCEqy+e29lahG5QLqmiUY=" + }, + "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==", + "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-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz", + "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6" + } + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==" + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "copy-props": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", + "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", + "requires": { + "each-props": "^1.3.0", + "is-plain-object": "^2.0.1" + } + }, + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cors": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", + "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-4.0.0.tgz", + "integrity": "sha512-6e5vDdrXZD+t5v0L8CrurPeybg4Fmf+FCSYxXKYVAqLUtyCSbuyqE059d0kDthTNRzKVjL7QMgNpEUlsoYH3iQ==", + "dev": true, + "requires": { + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.0.0", + "require-from-string": "^2.0.1" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "coveralls": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.1.tgz", + "integrity": "sha1-1wu5rMGDXsTwY/+drFQjwXsR8Xg=", + "requires": { + "js-yaml": "3.6.1", + "lcov-parse": "0.0.10", + "log-driver": "1.2.5", + "minimist": "1.2.0", + "request": "2.79.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "assert-plus": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", + "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=" + }, + "aws-sign2": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", + "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=" + }, + "caseless": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", + "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "form-data": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", + "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.5", + "mime-types": "^2.1.12" + } + }, + "har-validator": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", + "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "requires": { + "chalk": "^1.1.1", + "commander": "^2.9.0", + "is-my-json-valid": "^2.12.4", + "pinkie-promise": "^2.0.0" + } + }, + "http-signature": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", + "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "requires": { + "assert-plus": "^0.2.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "js-yaml": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", + "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "requires": { + "argparse": "^1.0.7", + "esprima": "^2.6.0" + } + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", + "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=" + }, + "request": { + "version": "2.79.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", + "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "requires": { + "aws-sign2": "~0.6.0", + "aws4": "^1.2.1", + "caseless": "~0.11.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.0", + "forever-agent": "~0.6.1", + "form-data": "~2.1.1", + "har-validator": "~2.0.6", + "hawk": "~3.1.3", + "http-signature": "~1.1.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.7", + "oauth-sign": "~0.8.1", + "qs": "~6.3.0", + "stringstream": "~0.0.4", + "tough-cookie": "~2.3.0", + "tunnel-agent": "~0.4.1", + "uuid": "^3.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "requires": { + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + } + } + }, + "cron": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz", + "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==", + "requires": { + "moment-timezone": "^0.5.x" + } + }, + "cross-env": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.0.5.tgz", + "integrity": "sha1-Q4PTZNlmCHPdGFs5ivO/717//vM=", + "requires": { + "cross-spawn": "^5.1.0", + "is-windows": "^1.0.0" + } + }, + "cross-fetch": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz", + "integrity": "sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ==", + "requires": { + "node-fetch": "2.6.1" + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cryptiles": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", + "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "requires": { + "boom": "2.x.x" + } + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" + }, + "cssstyle": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz", + "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==", + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" + } + } + }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=" + }, + "cz-conventional-changelog": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.0.0.tgz", + "integrity": "sha1-Val5r9/pXnAkh50qD1kkYwFwtTM=", + "requires": { + "conventional-commit-types": "^2.0.0", + "lodash.map": "^4.5.1", + "longest": "^1.0.1", + "pad-right": "^0.2.2", + "right-pad": "^1.0.1", + "word-wrap": "^1.0.3" + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "^0.10.9" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "dasherize": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz", + "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg=" + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "dateformat": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=" + }, + "debug": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.0.1.tgz", + "integrity": "sha512-6nVc6S36qbt/mutyt+UGMnawAMrPDZUPQjRZI3FS9tCtDRhvxJbK79unYBLPi+z5SLXQ3ftoVBFCblQtNSls8w==", + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "debug-fabulous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", + "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", + "requires": { + "debug": "3.X", + "memoizee": "0.4.X", + "object-assign": "4.X" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "requires": { + "mimic-response": "^1.0.0" + } + }, + "dedent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.6.0.tgz", + "integrity": "sha1-Dm2o8M5Sg471zsXI+TlrDBtko8s=" + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==" + }, + "default-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", + "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "requires": { + "kind-of": "^5.0.2" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "requires": { + "strip-bom": "^2.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, + "default-resolution": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=" + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "requires": { + "clone": "^1.0.2" + } + }, + "defer-to-connect": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", + "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==" + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "deprecated": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", + "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "detect-file": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", + "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", + "requires": { + "fs-exists-sync": "^0.1.0" + } + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "requires": { + "repeating": "^2.0.0" + } + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" + }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "diff": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=" + }, + "dns-prefetch-control": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz", + "integrity": "sha512-hvSnros73+qyZXhHFjx2CMLwoj3Fe7eR9EJsFsqmcI1bB2OBWL/+0YzaEaKssCHnj/6crawNnUyw74Gm2EKe+Q==" + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-walk": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "requires": { + "webidl-conversions": "^5.0.0" + } + }, + "dont-sniff-mimetype": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz", + "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==" + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "requires": { + "is-obj": "^2.0.0" + }, + "dependencies": { + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + } + } + }, + "dotenv": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", + "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=" + }, + "duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "requires": { + "readable-stream": "~1.1.9" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + } + } + }, + "each-props": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", + "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "requires": { + "is-plain-object": "^2.0.1", + "object.defaults": "^1.1.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "dev": true + }, + "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=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "end-of-stream": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", + "requires": { + "once": "~1.3.0" + }, + "dependencies": { + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "requires": { + "wrappy": "1" + } + } + } + }, + "engine.io": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.0.tgz", + "integrity": "sha512-XCyYVWzcHnK5cMz7G4VTu2W7zJS7SM1QkcelghyIk/FmobWBtXE7fwhBusEKvCSqc3bMh8fNFMlUkCKTFRxH2w==", + "requires": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "0.3.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "^7.1.2" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "engine.io-client": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.0.tgz", + "integrity": "sha512-a4J5QO2k99CM2a0b12IznnyQndoEvtA4UAldhGzKqnHf42I3Qs2W5SPnDvatZRcMaNZs4IevVicBPayxYt6FwA==", + "requires": { + "component-emitter": "1.2.1", + "component-inherit": "0.0.3", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "ws": "~6.1.0", + "xmlhttprequest-ssl": "~1.5.4", + "yeast": "0.1.2" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ws": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", + "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", + "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "envify": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/envify/-/envify-4.1.0.tgz", + "integrity": "sha512-IKRVVoAYr4pIx4yIWNsz9mOsboxlNXiu7TNBnem/K/uTHdkyzXWDzHCK7UTolqBbgaBz0tQHsD3YNls0uIIjiw==", + "requires": { + "esprima": "^4.0.0", + "through": "~2.3.4" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + } + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es5-ext": { + "version": "0.10.49", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.49.tgz", + "integrity": "sha512-3NMEhi57E31qdzmYp2jwRArIUsj1HI/RxbQ4bgnSB+AIKIxsAmTiK83bYMifIcpWvEc3P1X30DhUKOqEtF/kvg==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1", + "next-tick": "^1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "requires": { + "d": "1", + "es5-ext": "^0.10.14", + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "escape-goat": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", + "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==" + }, + "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", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "escodegen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", + "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } + } + }, + "eslint": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.6.1.tgz", + "integrity": "sha1-3cf8f9cL+TIFsLNEm7FqHp59SVA=", + "requires": { + "ajv": "^5.2.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^2.6.8", + "doctrine": "^2.0.0", + "eslint-scope": "^3.7.1", + "espree": "^3.5.0", + "esquery": "^1.0.0", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^9.17.0", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^4.0.0", + "progress": "^2.0.0", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", + "table": "^4.0.1", + "text-table": "~0.2.0" + }, + "dependencies": { + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", + "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + } + } + }, + "eslint-config-airbnb-base": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.0.0.tgz", + "integrity": "sha512-/XlFQGn3Mkwm642/GYBtOH3pgFX4Z7saBsqqyp96v0bEUPq24nIrZ6N72qAoD0lR2wAne4EC4YsHYkbPfaRfiA==", + "requires": { + "eslint-restricted-globals": "^0.1.1" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-module-utils": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz", + "integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==", + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-plugin-import": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", + "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", + "requires": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.1.1", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=" + }, + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-watch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-watch/-/eslint-watch-3.1.2.tgz", + "integrity": "sha1-uTs+ygiRXxE9yQCZT4gNsTZN5LM=", + "requires": { + "babel-polyfill": "^6.20.0", + "bluebird": "^3.4.7", + "chalk": "^1.1.3", + "chokidar": "^1.4.3", + "debug": "^2.6.3", + "keypress": "^0.2.1", + "lodash": "^4.17.4", + "optionator": "^0.8.2", + "source-map-support": "^0.4.14", + "text-table": "^0.2.0", + "unicons": "0.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=" + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + } + }, + "expand-tilde": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", + "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", + "requires": { + "os-homedir": "^1.0.1" + } + }, + "expect-ct": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz", + "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g==" + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "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.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + } + } + }, + "express-jwt": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/express-jwt/-/express-jwt-5.3.1.tgz", + "integrity": "sha512-1C9RNq0wMp/JvsH/qZMlg3SIPvKu14YkZ4YYv7gJQ1Vq+Dv8LH9tLKenS5vMNth45gTlEUGx+ycp9IHIlaHP/g==", + "requires": { + "async": "^1.5.0", + "express-unless": "^0.3.0", + "jsonwebtoken": "^8.1.0", + "lodash.set": "^4.0.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + } + } + }, + "express-unless": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/express-unless/-/express-unless-0.3.1.tgz", + "integrity": "sha1-JVfBRudb65A+LSR/m1ugFFJpbiA=" + }, + "express-validation": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/express-validation/-/express-validation-1.0.2.tgz", + "integrity": "sha1-fVid07JXxVs+AEZltsacsSzCsUI=", + "requires": { + "lodash": "^4.9.0" + } + }, + "express-winston": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/express-winston/-/express-winston-2.4.0.tgz", + "integrity": "sha1-J6ts2TBT4t/cNbzuoUoHfcfVLkk=", + "requires": { + "chalk": "~0.4.0", + "lodash": "~4.11.1" + }, + "dependencies": { + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=" + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "requires": { + "ansi-styles": "~1.0.0", + "has-color": "~0.1.0", + "strip-ansi": "~0.1.0" + } + }, + "lodash": { + "version": "4.11.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.11.2.tgz", + "integrity": "sha1-1rQzixEKWOIdrlzrz9u/0rxM2zs=" + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=" + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-1.1.1.tgz", + "integrity": "sha1-Etew24UPf/fnCBuvQAVwAGDEYAs=", + "requires": { + "extend": "^3.0.0", + "spawn-sync": "^1.0.15", + "tmp": "^0.0.29" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=" + }, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "feature-policy": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", + "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ==" + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "file-entry-cache": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", + "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "requires": { + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + } + } + }, + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=" + }, + "find-node-modules": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/find-node-modules/-/find-node-modules-1.0.4.tgz", + "integrity": "sha1-tt6zzMtpnIcDdne87eLF9YYrJVA=", + "requires": { + "findup-sync": "0.4.2", + "merge": "^1.2.0" + } + }, + "find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=" + }, + "find-root": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.0.0.tgz", + "integrity": "sha1-li/yEaqyXGUg/u641ih/j26VgHo=" + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "findup": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/findup/-/findup-0.1.5.tgz", + "integrity": "sha1-itkpozk7rGJ5V6fl3kYjsGsOLOs=", + "requires": { + "colors": "~0.6.0-1", + "commander": "~2.1.0" + }, + "dependencies": { + "colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=" + }, + "commander": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz", + "integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=" + } + } + }, + "findup-sync": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.2.tgz", + "integrity": "sha1-qBF9D3MST1pFRoOVef5S1xKfteU=", + "requires": { + "detect-file": "^0.1.0", + "is-glob": "^2.0.1", + "micromatch": "^2.3.7", + "resolve-dir": "^0.1.0" + } + }, + "fined": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.1.tgz", + "integrity": "sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==", + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "dependencies": { + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + } + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==" + }, + "flat-cache": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", + "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", + "requires": { + "circular-json": "^0.3.1", + "graceful-fs": "^4.1.2", + "rimraf": "~2.6.2", + "write": "^0.2.1" + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "format-util": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.3.tgz", + "integrity": "sha1-Ay3KShFiYqEsQ/TD7IVmQWxbLZU=" + }, + "formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==" + }, + "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", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "frameguard": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz", + "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g==" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-exists-sync": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", + "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=" + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true + }, + "aproba": { + "version": "1.2.0", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "optional": true + }, + "debug": { + "version": "4.1.1", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "delegates": { + "version": "1.0.0", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "optional": true + }, + "gauge": { + "version": "2.7.4", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "optional": true + }, + "minipass": { + "version": "2.3.5", + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "optional": true + }, + "needle": { + "version": "2.3.0", + "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "optional": true + }, + "once": { + "version": "1.4.0", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "optional": true + }, + "osenv": { + "version": "0.1.5", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "optional": true + }, + "readable-stream": { + "version": "2.3.6", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "optional": true + }, + "sax": { + "version": "1.2.4", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "optional": true + }, + "string_decoder": { + "version": "1.1.1", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-width": { + "version": "1.0.2", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "tar": { + "version": "4.4.8", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "optional": true + }, + "yallist": { + "version": "3.0.3", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + }, + "gaze": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", + "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", + "requires": { + "globule": "~0.1.0" + } + }, + "generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "requires": { + "is-property": "^1.0.2" + } + }, + "generate-object-property": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", + "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "requires": { + "is-property": "^1.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", + "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "glob-stream": { + "version": "3.1.18", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", + "requires": { + "glob": "^4.3.1", + "glob2base": "^0.0.12", + "minimatch": "^2.0.1", + "ordered-read-streams": "^0.1.0", + "through2": "^0.6.1", + "unique-stream": "^1.0.0" + }, + "dependencies": { + "glob": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^2.0.1", + "once": "^1.3.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "requires": { + "brace-expansion": "^1.0.0" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "glob-watcher": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", + "requires": { + "gaze": "^0.5.1" + } + }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "requires": { + "find-index": "^0.1.1" + } + }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "global-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", + "requires": { + "ini": "1.3.7" + }, + "dependencies": { + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==" + } + } + }, + "global-modules": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", + "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", + "requires": { + "global-prefix": "^0.1.4", + "is-windows": "^0.2.0" + }, + "dependencies": { + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=" + } + } + }, + "global-prefix": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", + "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", + "requires": { + "homedir-polyfill": "^1.0.0", + "ini": "^1.3.4", + "is-windows": "^0.2.0", + "which": "^1.2.12" + }, + "dependencies": { + "is-windows": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", + "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=" + } + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "globule": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", + "requires": { + "glob": "~3.1.21", + "lodash": "~1.0.1", + "minimatch": "~0.2.11" + }, + "dependencies": { + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "requires": { + "graceful-fs": "~1.2.0", + "inherits": "1", + "minimatch": "~0.2.11" + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=" + }, + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=" + }, + "lodash": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", + "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=" + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=" + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "requires": { + "lru-cache": "2", + "sigmund": "~1.0.0" + } + } + } + }, + "glogg": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", + "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", + "requires": { + "sparkles": "^1.0.0" + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "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==" + }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" + }, + "growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=" + }, + "gulp": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", + "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", + "requires": { + "archy": "^1.0.0", + "chalk": "^1.0.0", + "deprecated": "^0.0.1", + "gulp-util": "^3.0.0", + "interpret": "^1.0.0", + "liftoff": "^2.1.0", + "minimist": "^1.1.0", + "orchestrator": "^0.3.0", + "pretty-hrtime": "^1.0.0", + "semver": "^4.1.0", + "tildify": "^1.0.0", + "v8flags": "^2.0.2", + "vinyl-fs": "^0.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "semver": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", + "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } + } + }, + "gulp-babel": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-7.0.0.tgz", + "integrity": "sha512-TiUuFLW6FD2hx3mJ7QBPXN2nzpu6gRWFyjfChWxE1A9xaASRA5nsxrvHcqMDl5Ha6TvSBB9r74GbkVd1GO4mDA==", + "requires": { + "gulp-util": "^3.0.0", + "replace-ext": "0.0.1", + "through2": "^2.0.0", + "vinyl-sourcemaps-apply": "^0.2.0" + } + }, + "gulp-cli": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", + "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", + "requires": { + "ansi-colors": "^1.0.1", + "archy": "^1.0.0", + "array-sort": "^1.0.0", + "color-support": "^1.1.3", + "concat-stream": "^1.6.0", + "copy-props": "^2.0.1", + "fancy-log": "^1.3.2", + "gulplog": "^1.0.0", + "interpret": "^1.4.0", + "isobject": "^3.0.1", + "liftoff": "^3.1.0", + "matchdep": "^2.0.0", + "mute-stdout": "^1.0.0", + "pretty-hrtime": "^1.0.0", + "replace-homedir": "^1.0.0", + "semver-greatest-satisfied-range": "^1.1.0", + "v8flags": "^3.2.0", + "yargs": "^7.1.0" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "requires": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "requires": { + "homedir-polyfill": "^1.0.1" + } + } + } + }, + "gulp-load-plugins": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/gulp-load-plugins/-/gulp-load-plugins-1.5.0.tgz", + "integrity": "sha1-TEGffldk2aDjMGG6uWGPgbc9QXE=", + "requires": { + "array-unique": "^0.2.1", + "fancy-log": "^1.2.0", + "findup-sync": "^0.4.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "micromatch": "^2.3.8", + "resolve": "^1.1.7" + } + }, + "gulp-newer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/gulp-newer/-/gulp-newer-1.3.0.tgz", + "integrity": "sha1-1Q7Ky7gi7aSStXMkpshaB/2aVcE=", + "requires": { + "glob": "^7.0.3", + "gulp-util": "^3.0.7", + "kew": "^0.7.0" + } + }, + "gulp-nodemon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/gulp-nodemon/-/gulp-nodemon-2.5.0.tgz", + "integrity": "sha512-vXfaP72xo2C6XOaXrNcLEM3QqDJ1x21S3x97U4YtzN2Rl2kH57++aFkAVxe6BafGRSTxs/xVfE/jNNlCv5Ym2Q==", + "requires": { + "colors": "^1.2.1", + "gulp": "^4.0.0", + "nodemon": "^2.0.2" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + } + } + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + } + }, + "glob-watcher": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz", + "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==", + "requires": { + "anymatch": "^2.0.0", + "async-done": "^1.2.0", + "chokidar": "^2.0.0", + "is-negated-glob": "^1.0.0", + "just-debounce": "^1.0.0", + "object.defaults": "^1.1.0" + } + }, + "gulp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", + "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", + "requires": { + "glob-watcher": "^5.0.3", + "gulp-cli": "^2.2.0", + "undertaker": "^1.2.1", + "vinyl-fs": "^3.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "requires": { + "readable-stream": "^2.0.1" + } + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "requires": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + } + } } }, "gulp-sourcemaps": { @@ -4002,18 +23722,18 @@ "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.1.tgz", "integrity": "sha512-1qHCI3hdmsMdq/SUotxwUh/L8YzlI6J9zQ5ifNOtx4Y6KV5y5sGuORv1KZzWhuKtz/mXNh5xLESUtwC4EndCjA==", "requires": { - "@gulp-sourcemaps/identity-map": "1.0.1", - "@gulp-sourcemaps/map-sources": "1.0.0", - "acorn": "4.0.13", - "convert-source-map": "1.5.0", - "css": "2.2.1", - "debug-fabulous": "0.1.1", - "detect-newline": "2.1.0", - "graceful-fs": "4.1.11", - "source-map": "0.5.7", - "strip-bom-string": "1.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" + "@gulp-sourcemaps/identity-map": "1.X", + "@gulp-sourcemaps/map-sources": "1.X", + "acorn": "4.X", + "convert-source-map": "1.X", + "css": "2.X", + "debug-fabulous": ">=0.1.1", + "detect-newline": "2.X", + "graceful-fs": "4.X", + "source-map": "0.X", + "strip-bom-string": "1.X", + "through2": "2.X", + "vinyl": "1.X" }, "dependencies": { "acorn": { @@ -4026,8 +23746,8 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } } @@ -4038,35 +23758,52 @@ "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", "requires": { - "array-differ": "1.0.0", - "array-uniq": "1.0.3", - "beeper": "1.1.1", - "chalk": "1.1.3", - "dateformat": "2.0.0", - "fancy-log": "1.3.0", - "gulplog": "1.0.0", - "has-gulplog": "0.1.0", - "lodash._reescape": "3.0.0", - "lodash._reevaluate": "3.0.0", - "lodash._reinterpolate": "3.0.0", - "lodash.template": "3.6.2", - "minimist": "1.2.0", - "multipipe": "0.1.2", - "object-assign": "3.0.0", + "array-differ": "^1.0.0", + "array-uniq": "^1.0.2", + "beeper": "^1.0.0", + "chalk": "^1.0.0", + "dateformat": "^2.0.0", + "fancy-log": "^1.1.0", + "gulplog": "^1.0.0", + "has-gulplog": "^0.1.0", + "lodash._reescape": "^3.0.0", + "lodash._reevaluate": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.template": "^3.0.0", + "minimist": "^1.1.0", + "multipipe": "^0.1.2", + "object-assign": "^3.0.0", "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl": "0.5.3" + "through2": "^2.0.0", + "vinyl": "^0.5.0" }, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } }, "object-assign": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } }, @@ -4075,27 +23812,30 @@ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", "requires": { - "glogg": "1.0.0" + "glogg": "^1.0.0" } }, "handlebars": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", - "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", - "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" }, "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "requires": { - "amdefine": "1.0.1" - } + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -4105,22 +23845,20 @@ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "requires": { - "chalk": "1.1.3", - "commander": "2.11.0", - "is-my-json-valid": "2.16.1", - "pinkie-promise": "2.0.1" + "ajv": "^6.5.5", + "har-schema": "^2.0.0" } }, "has": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", - "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "requires": { - "function-bind": "1.1.1" + "function-bind": "^1.1.1" } }, "has-ansi": { @@ -4128,7 +23866,22 @@ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" + } + }, + "has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "requires": { + "isarray": "2.0.1" + }, + "dependencies": { + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } } }, "has-color": { @@ -4136,66 +23889,148 @@ "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=" }, + "has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" + }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-gulplog": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", "requires": { - "sparkles": "1.0.0" + "sparkles": "^1.0.0" + } + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } } }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==" + }, "hawk": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "boom": "2.x.x", + "cryptiles": "2.x.x", + "hoek": "2.x.x", + "sntp": "1.x.x" } }, "helmet": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.8.1.tgz", - "integrity": "sha512-HzcpQ74kE1gNFvTd8fI/Nz2N0b0Aa/38dSiSVt/ijkwjc50tUp5siXTE9lTBibQ4JlRzp/35Qf+j2bZgHYwg1g==", - "requires": { - "connect": "3.6.2", - "dns-prefetch-control": "0.1.0", - "dont-sniff-mimetype": "1.0.0", - "expect-ct": "0.1.0", - "frameguard": "3.0.0", - "helmet-csp": "2.5.1", - "hide-powered-by": "1.0.0", + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.1.tgz", + "integrity": "sha512-IC/54Lxvvad2YiUdgLmPlNFKLhNuG++waTF5KPYq/Feo3NNhqMFbcLAlbVkai+9q0+4uxjxGPJ9bNykG+3zZNg==", + "requires": { + "depd": "2.0.0", + "dns-prefetch-control": "0.2.0", + "dont-sniff-mimetype": "1.1.0", + "expect-ct": "0.2.0", + "feature-policy": "0.3.0", + "frameguard": "3.1.0", + "helmet-crossdomain": "0.4.0", + "helmet-csp": "2.9.2", + "hide-powered-by": "1.1.0", "hpkp": "2.0.0", - "hsts": "2.1.0", - "ienoopen": "1.0.0", - "nocache": "2.0.0", - "referrer-policy": "1.1.0", - "x-xss-protection": "1.0.0" + "hsts": "2.2.0", + "ienoopen": "1.1.0", + "nocache": "2.1.0", + "referrer-policy": "1.2.0", + "x-xss-protection": "1.3.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } } }, + "helmet-crossdomain": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz", + "integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA==" + }, "helmet-csp": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.5.1.tgz", - "integrity": "sha512-PLLch8wVcVF2+ViTtSGHIvXqQVjcwGRtBwrNPggC+j28J7eSoPHxbJBr9SvLgh9V3HZa0C1zZFZ6gYVLIrPD0Q==", + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.9.2.tgz", + "integrity": "sha512-Lt5WqNfbNjEJ6ysD4UNpVktSyjEKfU9LVJ1LaFmPfYseg/xPealPfgHhtqdAdjPDopp5zbg/VWCyp4cluMIckw==", "requires": { + "bowser": "^2.6.1", "camelize": "1.0.0", - "content-security-policy-builder": "1.1.0", - "dasherize": "2.0.0", - "lodash.reduce": "4.6.0", - "platform": "1.3.4" + "content-security-policy-builder": "2.1.0", + "dasherize": "2.0.0" } }, "hide-powered-by": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz", - "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys=" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz", + "integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg==" }, "hoek": { "version": "2.16.3", @@ -4207,16 +24042,16 @@ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" } }, "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "requires": { - "parse-passwd": "1.0.0" + "parse-passwd": "^1.0.0" } }, "hooks-fixed": { @@ -4225,9 +24060,9 @@ "integrity": "sha1-oB2JTVKsf2WZu7H2PfycQR33DLo=" }, "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" }, "hpkp": { "version": "2.0.0", @@ -4235,29 +24070,132 @@ "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI=" }, "hsts": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.1.0.tgz", - "integrity": "sha512-zXhh/DqgrTXJ7erTN6Fh5k/xjMhDGXCqdYN3wvxUvGUQvnxcFfUd8E+6vLg/nk3ss1TYMb+DhRl25fYABioTvA==" + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz", + "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==", + "requires": { + "depd": "2.0.0" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "http": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/http/-/http-0.0.1-security.tgz", + "integrity": "sha512-RnDvP10Ty9FxqOtPZuxtebw1j4L/WiqNMDtuc1YMH1XQm5TgDRaR1G9u8upL6KD1bXHSp9eSXo/ED+8Q7FAr+g==" + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "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.1", + "depd": "~1.1.2", "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.3.1" + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.0.6.tgz", + "integrity": "sha512-NyL6ZB6cVni7pl+/IT2W0ni5ME00xR0sN27AQZZrpKn1b+qRh+mLbBxIq9Cq1oGfmTc7BUq4HB77mxwCaxAYNg==", + "requires": { + "@types/http-proxy": "^1.17.4", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.20", + "micromatch": "^4.0.2" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } } }, "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.13.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, "http-status": { @@ -4265,15 +24203,39 @@ "resolved": "https://registry.npmjs.org/http-status/-/http-status-1.0.1.tgz", "integrity": "sha1-3EMAGov8UKyH1IWokvdXiWS8lKI=" }, + "https": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", + "integrity": "sha1-PDfHrhqO65ZpBKKtHpdaGUt+06Q=" + }, + "https-proxy-agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "requires": { + "agent-base": "5", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, "husky": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", "dev": true, "requires": { - "is-ci": "1.0.10", - "normalize-path": "1.0.0", - "strip-indent": "2.0.0" + "is-ci": "^1.0.10", + "normalize-path": "^1.0.0", + "strip-indent": "^2.0.0" }, "dependencies": { "normalize-path": { @@ -4295,14 +24257,14 @@ "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" }, "ienoopen": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.0.0.tgz", - "integrity": "sha1-NGpCj0dKrI9QzzeE6i0PFvYr2ms=" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", + "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==" }, "ignore": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz", - "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==" + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==" }, "ignore-by-default": { "version": "1.0.1", @@ -4325,16 +24287,21 @@ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, + "indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -4343,56 +24310,98 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inquirer": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-1.2.3.tgz", "integrity": "sha1-TexvMvN+97sLLtPx0aXD9UUHSRg=", "requires": { - "ansi-escapes": "1.4.0", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.2.0", - "external-editor": "1.1.1", - "figures": "1.7.0", - "lodash": "4.17.4", + "ansi-escapes": "^1.1.0", + "chalk": "^1.0.0", + "cli-cursor": "^1.0.1", + "cli-width": "^2.0.0", + "external-editor": "^1.1.0", + "figures": "^1.3.5", + "lodash": "^4.3.0", "mute-stream": "0.0.6", - "pinkie-promise": "2.0.1", - "run-async": "2.3.0", - "rx": "4.1.0", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" + "pinkie-promise": "^2.0.0", + "run-async": "^2.2.0", + "rx": "^4.1.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } } }, "interpret": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" }, "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "requires": { - "loose-envify": "1.3.1" + "loose-envify": "^1.0.0" } }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" + }, "ipaddr.js": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz", - "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA=" + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" }, "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { - "is-relative": "0.2.1", - "is-windows": "0.2.0" + "kind-of": "^3.0.2" } }, "is-arrayish": { @@ -4405,29 +24414,46 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "requires": { - "binary-extensions": "1.10.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, "requires": { - "builtin-modules": "1.1.1" + "ci-info": "^1.5.0" } }, - "is-ci": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", - "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", - "dev": true, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "requires": { - "ci-info": "1.1.2" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } } }, "is-directory": { @@ -4446,7 +24472,7 @@ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "requires": { - "is-primitive": "2.0.0" + "is-primitive": "^2.0.0" } }, "is-extendable": { @@ -4464,7 +24490,7 @@ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { @@ -4472,7 +24498,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-glob": { @@ -4480,37 +24506,65 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "requires": { - "is-extglob": "1.0.0" + "is-extglob": "^1.0.0" + } + }, + "is-installed-globally": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz", + "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==", + "requires": { + "global-dirs": "^2.0.1", + "is-path-inside": "^3.0.1" + }, + "dependencies": { + "is-path-inside": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz", + "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==" + } } }, + "is-my-ip-valid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==" + }, "is-my-json-valid": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz", - "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==", + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", + "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" + "generate-function": "^2.0.0", + "generate-object-property": "^1.1.0", + "is-my-ip-valid": "^1.0.0", + "jsonpointer": "^4.0.0", + "xtend": "^4.0.0" } }, - "is-npm": { + "is-negated-glob": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=" + }, + "is-npm": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz", + "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==" }, "is-number": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" } }, "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true }, "is-observable": { "version": "0.2.0", @@ -4518,7 +24572,7 @@ "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", "dev": true, "requires": { - "symbol-observable": "0.2.4" + "symbol-observable": "^0.2.2" } }, "is-path-cwd": { @@ -4527,19 +24581,19 @@ "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" }, "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", "requires": { - "is-path-inside": "1.0.0" + "is-path-inside": "^1.0.0" } }, "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-object": { @@ -4547,7 +24601,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -4562,6 +24616,11 @@ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=" + }, "is-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", @@ -4577,11 +24636,6 @@ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" - }, "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", @@ -4589,30 +24643,23 @@ "dev": true }, "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", - "requires": { - "is-unc-path": "0.1.2" - } - }, - "is-resolvable": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", "requires": { - "tryit": "1.0.3" + "is-unc-path": "^1.0.0" } }, - "is-retry-allowed": { + "is-resolvable": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==" }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true }, "is-typedarray": { "version": "1.0.0", @@ -4620,11 +24667,11 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", "requires": { - "unc-path-regex": "0.1.2" + "unc-path-regex": "^0.1.2" } }, "is-utf8": { @@ -4632,21 +24679,26 @@ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=" + }, "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, - "isemail": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz", - "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=" - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4670,14 +24722,14 @@ "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-1.0.0-alpha.2.tgz", "integrity": "sha1-BglrwI6Yuq10Sq5Gli2N+frGPQg=", "requires": { - "abbrev": "1.0.9", - "async": "1.5.2", - "istanbul-api": "1.1.14", - "js-yaml": "3.6.1", - "mkdirp": "0.5.1", - "nopt": "3.0.6", - "which": "1.3.0", - "wordwrap": "1.0.0" + "abbrev": "1.0.x", + "async": "1.x", + "istanbul-api": "^1.0.0-alpha", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "which": "^1.1.1", + "wordwrap": "^1.0.0" }, "dependencies": { "abbrev": { @@ -4685,94 +24737,99 @@ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=" }, + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "requires": { - "abbrev": "1.0.9" + "abbrev": "1" } } } }, "istanbul-api": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.14.tgz", - "integrity": "sha1-JbxXAffGgMD//5E95G42GaOm5oA=", - "requires": { - "async": "2.5.0", - "fileset": "2.0.3", - "istanbul-lib-coverage": "1.1.1", - "istanbul-lib-hook": "1.0.7", - "istanbul-lib-instrument": "1.8.0", - "istanbul-lib-report": "1.1.1", - "istanbul-lib-source-maps": "1.2.1", - "istanbul-reports": "1.1.2", - "js-yaml": "3.10.0", - "mkdirp": "0.5.1", - "once": "1.4.0" + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.7.tgz", + "integrity": "sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA==", + "requires": { + "async": "^2.1.4", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.1", + "istanbul-lib-hook": "^1.2.2", + "istanbul-lib-instrument": "^1.10.2", + "istanbul-lib-report": "^1.1.5", + "istanbul-lib-source-maps": "^1.2.6", + "istanbul-reports": "^1.5.1", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" }, "dependencies": { "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "requires": { - "lodash": "4.17.4" + "lodash": "^4.17.11" } }, "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } } } }, "istanbul-lib-coverage": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", - "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz", + "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==" }, "istanbul-lib-hook": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz", - "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz", + "integrity": "sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw==", "requires": { - "append-transform": "0.4.0" + "append-transform": "^0.4.0" } }, "istanbul-lib-instrument": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz", - "integrity": "sha1-ZvbJQhzJ7EcE928tsIS6kHiitTI=", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz", + "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==", "requires": { - "babel-generator": "6.26.0", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "istanbul-lib-coverage": "1.1.1", - "semver": "5.4.1" + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.1", + "semver": "^5.3.0" } }, "istanbul-lib-report": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", - "integrity": "sha512-tvF+YmCmH4thnez6JFX06ujIA19WPa9YUiwjc1uALF2cv5dmE3It8b5I8Ob7FHJ70H9Y5yF+TDkVa/mcADuw1Q==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz", + "integrity": "sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw==", "requires": { - "istanbul-lib-coverage": "1.1.1", - "mkdirp": "0.5.1", - "path-parse": "1.0.5", - "supports-color": "3.2.3" + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" }, "dependencies": { "has-flag": { @@ -4785,45 +24842,45 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } }, "istanbul-lib-source-maps": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz", - "integrity": "sha512-mukVvSXCn9JQvdJl8wP/iPhqig0MRtuWuD4ZNKo6vB2Ik//AmhAKe3QnPN02dmkRe3lTudFk3rzoHhwU4hb94w==", - "requires": { - "debug": "2.6.9", - "istanbul-lib-coverage": "1.1.1", - "mkdirp": "0.5.1", - "rimraf": "2.6.1", - "source-map": "0.5.7" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz", + "integrity": "sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg==", + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.1", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } } } }, "istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha1-D7Lj9qqZIr085F0F2KtNXo4HvU8=", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.5.1.tgz", + "integrity": "sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw==", "requires": { - "handlebars": "4.0.10" + "handlebars": "^4.0.3" } }, "items": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/items/-/items-2.1.1.tgz", - "integrity": "sha1-i9FtnIOxlSneWuoyGsqtp4NkoZg=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/items/-/items-2.1.2.tgz", + "integrity": "sha512-kezcEqgB97BGeZZYtX/MA8AG410ptURstvnz5RAgyFZ8wQFPMxHY8GpTq+/ZHKT3frSlIthUq7EvLt9xn3TvXg==" }, "jest-get-type": { "version": "21.2.0", @@ -4837,41 +24894,10 @@ "integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==", "dev": true, "requires": { - "chalk": "2.3.0", - "jest-get-type": "21.2.0", - "leven": "2.1.0", - "pretty-format": "21.2.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.0" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - } + "chalk": "^2.0.1", + "jest-get-type": "^21.2.0", + "leven": "^2.1.0", + "pretty-format": "^21.2.1" } }, "jmespath": { @@ -4884,16 +24910,16 @@ "resolved": "https://registry.npmjs.org/joi/-/joi-10.6.0.tgz", "integrity": "sha512-hBF3LcqyAid+9X/pwg+eXjD2QBZI5eXnBFJYaAkH4SK3mp9QSRiiQnDYlmlz5pccMvnLcJRS4whhDOTCkmsAdQ==", "requires": { - "hoek": "4.2.0", - "isemail": "2.2.1", - "items": "2.1.1", - "topo": "2.0.2" + "hoek": "4.x.x", + "isemail": "2.x.x", + "items": "2.x.x", + "topo": "2.x.x" }, "dependencies": { "hoek": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", + "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==" }, "isemail": { "version": "2.2.1", @@ -4905,7 +24931,7 @@ "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz", "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=", "requires": { - "hoek": "4.2.0" + "hoek": "4.x.x" } } } @@ -4916,30 +24942,82 @@ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, "js-yaml": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz", - "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "requires": { - "argparse": "1.0.9", - "esprima": "2.7.3" + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + } } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "optional": true - }, - "jschardet": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz", - "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A==" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "jsdom": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.0.tgz", + "integrity": "sha512-6VaW3UWyKbm9DFVIAgTfhuwnvqiqlRYNg5Rk6dINTVoZT0eKz+N86vQZr+nqt1ny1lSB1TWZJWSEWQAfu8oTpA==", + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.4", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.13.0", + "html-encoding-sniffer": "^2.0.0", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.0", + "request-promise-native": "^1.0.8", + "saxes": "^4.0.2", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^5.0.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.1", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + } + } }, "jsesc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -4950,11 +25028,11 @@ "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-1.4.1.tgz", "integrity": "sha1-wMLkOL8HlnI7AkUbrovH3Qs3/tA=", "requires": { - "call-me-maybe": "1.0.1", - "debug": "2.6.9", - "es6-promise": "3.3.1", - "js-yaml": "3.6.1", - "ono": "2.2.5" + "call-me-maybe": "^1.0.1", + "debug": "^2.2.0", + "es6-promise": "^3.0.2", + "js-yaml": "^3.4.6", + "ono": "^2.0.1" }, "dependencies": { "debug": { @@ -4965,6 +25043,11 @@ "ms": "2.0.0" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "ono": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/ono/-/ono-2.2.5.tgz", @@ -4973,18 +25056,23 @@ } }, "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", "requires": { - "jsonify": "0.0.0" + "jsonify": "~0.0.0" } }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -5005,7 +25093,7 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.6" } }, "jsonify": { @@ -5023,17 +25111,17 @@ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.0.0.tgz", "integrity": "sha1-eyQapnxhs9Cz5kElSppvW2b1UOg=", "requires": { - "jws": "3.1.4", - "lodash.includes": "4.3.0", - "lodash.isarray": "4.0.0", - "lodash.isboolean": "3.0.3", - "lodash.isinteger": "4.0.4", - "lodash.isnumber": "3.0.3", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.once": "4.1.1", - "ms": "2.0.0", - "xtend": "4.0.1" + "jws": "^3.1.4", + "lodash.includes": "^4.3.0", + "lodash.isarray": "^4.0.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.0.0", + "xtend": "^4.0.1" }, "dependencies": { "lodash.isarray": { @@ -5052,40 +25140,41 @@ "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } } }, + "jstoxml": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/jstoxml/-/jstoxml-1.6.7.tgz", + "integrity": "sha512-XTVwGdi/saJtJgiLvl9Fi/J7GsFuRiOER52QIlYv+10vq2LANx/l+d/AvbAF2kF3UOQF2dkW09WzqKH1z148XQ==" + }, + "just-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", + "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=" + }, "just-extend": { - "version": "1.1.27", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", - "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", "dev": true }, "jwa": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.5.tgz", - "integrity": "sha1-oFUs4CIHQs1S4VN3SjKQXDDnVuU=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", "requires": { - "base64url": "2.0.0", "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.9", - "safe-buffer": "5.1.1" + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" } }, "jws": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.4.tgz", - "integrity": "sha1-+ei5M46KhHJ31kRLFGT2GIDgUKI=", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", "requires": { - "base64url": "2.0.0", - "jwa": "1.1.5", - "safe-buffer": "5.1.1" + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" } }, "kareem": { @@ -5103,12 +25192,20 @@ "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz", "integrity": "sha1-HoBFQlABjbrUw/6USX1uZ7YmnHc=" }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "requires": { + "json-buffer": "3.0.0" + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "requires": { - "is-buffer": "1.1.5" + "is-buffer": "^1.1.5" } }, "klaw": { @@ -5116,28 +25213,55 @@ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "requires": { - "graceful-fs": "4.1.11" + "graceful-fs": "^4.1.9" + } + }, + "last-run": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", + "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "requires": { + "default-resolution": "^2.0.0", + "es6-weak-map": "^2.0.1" } }, "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", "requires": { - "package-json": "4.0.1" + "package-json": "^6.3.0" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "optional": true + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } }, "lcov-parse": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=" }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "requires": { + "flush-write-stream": "^1.0.2" + } + }, "leven": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", @@ -5149,81 +25273,391 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "liftoff": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", - "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", - "requires": { - "extend": "3.0.1", - "findup-sync": "0.4.2", - "fined": "1.1.0", - "flagged-respawn": "0.3.2", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.mapvalues": "4.6.0", - "rechoir": "0.6.2", - "resolve": "1.4.0" + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", + "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "requires": { + "extend": "^3.0.0", + "findup-sync": "^2.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + } } }, "lint-staged": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-6.0.0.tgz", - "integrity": "sha512-ZUftK94S4vedpQG1LlA2tc2AuQXXBwc+1lB+j8SEfG5+p2dqu3Ug8iYQ8jdap+uLkhDw4OaJXqE+CZ/L+vfv+Q==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-6.1.1.tgz", + "integrity": "sha512-M/7bwLdXbeG7ZNLcasGeLMBDg60/w6obj3KOtINwJyxAxb53XGY0yH5FSZlWklEzuVbTtqtIfAajh6jYIN90AA==", "dev": true, "requires": { - "app-root-path": "2.0.1", - "chalk": "2.3.0", - "commander": "2.11.0", - "cosmiconfig": "3.1.0", - "debug": "3.1.0", - "dedent": "0.7.0", - "execa": "0.8.0", - "find-parent-dir": "0.3.0", - "is-glob": "4.0.0", - "jest-validate": "21.2.1", - "listr": "0.13.0", - "lodash": "4.17.4", - "log-symbols": "2.1.0", - "minimatch": "3.0.4", - "npm-which": "3.0.1", - "p-map": "1.1.1", - "path-is-inside": "1.0.2", - "pify": "3.0.0", - "staged-git-files": "0.0.4", - "stringify-object": "3.2.1" + "app-root-path": "^2.0.0", + "chalk": "^2.1.0", + "commander": "^2.11.0", + "cosmiconfig": "^4.0.0", + "debug": "^3.1.0", + "dedent": "^0.7.0", + "execa": "^0.8.0", + "find-parent-dir": "^0.3.0", + "is-glob": "^4.0.0", + "jest-validate": "^21.1.0", + "listr": "^0.13.0", + "lodash": "^4.17.4", + "log-symbols": "^2.0.0", + "minimatch": "^3.0.0", + "npm-which": "^3.0.1", + "p-map": "^1.1.1", + "path-is-inside": "^1.0.2", + "pify": "^3.0.0", + "staged-git-files": "1.0.0", + "stringify-object": "^3.2.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.0" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "dedent": { @@ -5238,13 +25672,13 @@ "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", "dev": true, "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" } }, "is-extglob": { @@ -5259,16 +25693,7 @@ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "2.1.1" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" + "is-extglob": "^2.1.1" } } } @@ -5279,33 +25704,58 @@ "integrity": "sha1-ILsLowuuZg7oTMBQPfS+PVYjiH0=", "dev": true, "requires": { - "chalk": "1.1.3", - "cli-truncate": "0.2.1", - "figures": "1.7.0", - "indent-string": "2.1.0", - "is-observable": "0.2.0", - "is-promise": "2.1.0", - "is-stream": "1.1.0", - "listr-silent-renderer": "1.1.1", - "listr-update-renderer": "0.4.0", - "listr-verbose-renderer": "0.4.1", - "log-symbols": "1.0.2", - "log-update": "1.0.2", - "ora": "0.2.3", - "p-map": "1.1.1", - "rxjs": "5.5.5", - "stream-to-observable": "0.2.0", - "strip-ansi": "3.0.1" + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-observable": "^0.2.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.4.0", + "listr-verbose-renderer": "^0.4.0", + "log-symbols": "^1.0.2", + "log-update": "^1.0.2", + "ora": "^0.2.3", + "p-map": "^1.1.1", + "rxjs": "^5.4.2", + "stream-to-observable": "^0.2.0", + "strip-ansi": "^3.0.1" }, "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, "log-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "dev": true, "requires": { - "chalk": "1.1.3" + "chalk": "^1.0.0" } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, @@ -5321,16 +25771,35 @@ "integrity": "sha1-NE2YDaLKLosUW6MFkI8yrj9MyKc=", "dev": true, "requires": { - "chalk": "1.1.3", - "cli-truncate": "0.2.1", - "elegant-spinner": "1.0.1", - "figures": "1.7.0", - "indent-string": "3.2.0", - "log-symbols": "1.0.2", - "log-update": "1.0.2", - "strip-ansi": "3.0.1" + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^1.0.2", + "strip-ansi": "^3.0.1" }, "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, "indent-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", @@ -5343,8 +25812,14 @@ "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", "dev": true, "requires": { - "chalk": "1.1.3" + "chalk": "^1.0.0" } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, @@ -5354,10 +25829,37 @@ "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=", "dev": true, "requires": { - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "date-fns": "1.29.0", - "figures": "1.7.0" + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } } }, "load-json-file": { @@ -5365,10 +25867,10 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" }, "dependencies": { "pify": { @@ -5378,13 +25880,18 @@ } } }, + "load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" + }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "dependencies": { "path-exists": { @@ -5395,17 +25902,17 @@ } }, "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash._baseassign": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" } }, "lodash._basecopy": { @@ -5428,21 +25935,6 @@ "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" }, - "lodash._bindcallback": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", - "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" - }, - "lodash._createassigner": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz", - "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", - "requires": { - "lodash._bindcallback": "3.0.1", - "lodash._isiterateecall": "3.0.9", - "lodash.restparam": "3.6.1" - } - }, "lodash._getnative": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", @@ -5473,16 +25965,6 @@ "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" }, - "lodash.assign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz", - "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=", - "requires": { - "lodash._baseassign": "3.2.0", - "lodash._createassigner": "3.1.1", - "lodash.keys": "3.1.2" - } - }, "lodash.chunk": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", @@ -5498,18 +25980,9 @@ "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", "requires": { - "lodash._baseassign": "3.2.0", - "lodash._basecreate": "3.0.3", - "lodash._isiterateecall": "3.0.9" - } - }, - "lodash.defaults": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-3.1.2.tgz", - "integrity": "sha1-xzCLGNv4vJNy1wGnNJPGEZK9Liw=", - "requires": { - "lodash.assign": "3.2.0", - "lodash.restparam": "3.6.1" + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" } }, "lodash.escape": { @@ -5517,9 +25990,14 @@ "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", "requires": { - "lodash._root": "3.0.1" + "lodash._root": "^3.0.0" } }, + "lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM=" + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -5575,9 +26053,9 @@ "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, "lodash.map": { @@ -5585,21 +26063,11 @@ "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=" }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=" - }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, - "lodash.reduce": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", - "integrity": "sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs=" - }, "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -5610,20 +26078,25 @@ "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + }, "lodash.template": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", "requires": { - "lodash._basecopy": "3.0.1", - "lodash._basetostring": "3.0.1", - "lodash._basevalues": "3.0.0", - "lodash._isiterateecall": "3.0.9", - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0", - "lodash.keys": "3.1.2", - "lodash.restparam": "3.6.1", - "lodash.templatesettings": "3.1.1" + "lodash._basecopy": "^3.0.0", + "lodash._basetostring": "^3.0.0", + "lodash._basevalues": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0", + "lodash.keys": "^3.0.0", + "lodash.restparam": "^3.0.0", + "lodash.templatesettings": "^3.0.0" } }, "lodash.templatesettings": { @@ -5631,8 +26104,8 @@ "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0" + "lodash._reinterpolate": "^3.0.0", + "lodash.escape": "^3.0.0" } }, "log-driver": { @@ -5641,43 +26114,12 @@ "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=" }, "log-symbols": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.1.0.tgz", - "integrity": "sha512-zLeLrzMA1A2vRF1e/0Mo+LNINzi6jzBylHj5WqvQ/WK/5WCZt8si9SyN4p9llr/HRYvVR1AoXHRHl4WTHyQAzQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", "dev": true, "requires": { - "chalk": "2.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.0" - } - }, - "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - } + "chalk": "^2.0.1" } }, "log-update": { @@ -5686,14 +26128,14 @@ "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", "dev": true, "requires": { - "ansi-escapes": "1.4.0", - "cli-cursor": "1.0.2" + "ansi-escapes": "^1.0.0", + "cli-cursor": "^1.0.2" } }, "lolex": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", - "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==", + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", "dev": true }, "longest": { @@ -5702,25 +26144,30 @@ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "requires": { - "js-tokens": "3.0.2" + "js-tokens": "^3.0.0 || ^4.0.0" } }, "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + }, + "lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" }, "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "lru-queue": { @@ -5728,7 +26175,7 @@ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", "requires": { - "es5-ext": "0.10.30" + "es5-ext": "~0.10.2" } }, "mailparser": { @@ -5736,36 +26183,401 @@ "resolved": "https://registry.npmjs.org/mailparser/-/mailparser-0.6.2.tgz", "integrity": "sha1-A8SGA5vfTfbNO2rcqqxBB9/bwGg=", "requires": { - "encoding": "0.1.12", - "mime": "1.3.4", - "mimelib": "0.3.1", - "uue": "3.1.1" + "encoding": "^0.1.12", + "mime": "^1.3.4", + "mimelib": "^0.3.0", + "uue": "^3.1.0" } }, "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "requires": { + "kind-of": "^6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-visit": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", - "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "requires": { - "pify": "2.3.0" + "object-visit": "^1.0.0" + } + }, + "matchdep": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", + "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "requires": { + "findup-sync": "^2.0.0", + "micromatch": "^3.0.4", + "resolve": "^1.4.0", + "stack-trace": "0.0.10" }, "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "findup-sync": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^3.1.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } } } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=" + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" }, "media-typer": { "version": "0.3.0", @@ -5773,24 +26585,30 @@ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "memoizee": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.9.tgz", - "integrity": "sha1-6hwAX1xMMdiaShDiTbg/v2HN1PM=", + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz", + "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.30", - "es6-weak-map": "2.0.2", - "event-emitter": "0.3.5", - "is-promise": "2.1.0", - "lru-queue": "0.1.0", - "next-tick": "1.0.0", - "timers-ext": "0.1.2" + "d": "1", + "es5-ext": "^0.10.45", + "es6-weak-map": "^2.0.2", + "event-emitter": "^0.3.5", + "is-promise": "^2.1", + "lru-queue": "0.1", + "next-tick": "1", + "timers-ext": "^0.1.5" } }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "merge": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz", - "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==" }, "merge-descriptors": { "version": "1.0.1", @@ -5803,9 +26621,9 @@ "integrity": "sha1-vRUfLONM8Bp2ykAKuVwBKxAtj3E=", "requires": { "debug": "2.6.8", - "methods": "1.1.2", - "parseurl": "1.3.1", - "vary": "1.1.1" + "methods": "~1.1.2", + "parseurl": "~1.3.1", + "vary": "~1.1.1" }, "dependencies": { "debug": { @@ -5815,6 +26633,11 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -5828,37 +26651,76 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "migrate": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/migrate/-/migrate-1.6.2.tgz", + "integrity": "sha512-XAFab+ArPTo9BHzmihKjsZ5THKRryenA+lwob0R+ax0hLDs7YzJFJT5YZE3gtntZgzdgcuFLs82EJFB/Dssr+g==", + "requires": { + "chalk": "^1.1.3", + "commander": "^2.9.0", + "dateformat": "^2.0.0", + "dotenv": "^4.0.0", + "inherits": "^2.0.3", + "minimatch": "^3.0.3", + "mkdirp": "^0.5.1", + "slug": "^0.9.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } } }, "mime": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz", - "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM=" + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" }, "mime-types": { - "version": "2.1.17", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", - "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", "requires": { - "mime-db": "1.30.0" + "mime-db": "~1.38.0" } }, "mimelib": { @@ -5866,33 +26728,74 @@ "resolved": "https://registry.npmjs.org/mimelib/-/mimelib-0.3.1.tgz", "integrity": "sha1-eHrdJBXYJ6yzr27EvKHqlZZBiFM=", "requires": { - "addressparser": "1.0.1", - "encoding": "0.1.12" + "addressparser": "~1.0.1", + "encoding": "~0.1.12" } }, "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "^1.1.7" } }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=" + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + } + } }, "mocha": { "version": "3.5.0", @@ -5917,7 +26820,7 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "requires": { - "graceful-readlink": "1.0.1" + "graceful-readlink": ">= 1.0.0" } }, "debug": { @@ -5933,12 +26836,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-flag": { @@ -5946,59 +26849,52 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "supports-color": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", "requires": { - "has-flag": "1.0.0" + "has-flag": "^1.0.0" } } } }, "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=" + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "moment-timezone": { + "version": "0.5.27", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.27.tgz", + "integrity": "sha512-EIKQs7h5sAsjhPCqN6ggx6cEbs94GK050254TIJySD1bzoM5JTYDwAU1IoVOeTOL6Gm27kYJ51/uuvq1kIlrbw==", + "requires": { + "moment": ">= 2.9.0" + } }, "mongodb": { - "version": "2.2.31", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.31.tgz", - "integrity": "sha1-GUBEXGYeGSF7s7+CRdmFSq71SNs=", + "version": "3.1.13", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.1.13.tgz", + "integrity": "sha512-sz2dhvBZQWf3LRNDhbd30KHVzdjZx9IKC0L+kSZ/gzYquCF5zPOgGqRz6sSCqYZtKP2ekB4nfLxhGtzGHnIKxA==", "requires": { - "es6-promise": "3.2.1", - "mongodb-core": "2.1.15", - "readable-stream": "2.2.7" - }, - "dependencies": { - "es6-promise": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" - }, - "readable-stream": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - } + "mongodb-core": "3.1.11", + "safe-buffer": "^5.1.2" } }, "mongodb-core": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.15.tgz", - "integrity": "sha1-hB9TuH//9MdFgYnDXIroJ+EWl2Q=", + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.1.11.tgz", + "integrity": "sha512-rD2US2s5qk/ckbiiGFHeu+yKYDXdJ1G87F6CG3YdaZpzdOm5zpoAZd/EKbPmFO6cQZ+XVXBXBJ660sSI0gc6qg==", "requires": { - "bson": "1.0.4", - "require_optional": "1.0.1" + "bson": "^1.1.0", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" } }, "mongoose": { @@ -6007,7 +26903,7 @@ "integrity": "sha512-+D+sS0aU1asnVhHCZnR9PHnaeJqcN+E9v3vMApbru8KRMbHek06njMnZ7EPLjQffwwXm/wnFVQ8OeF9EfOp9pA==", "requires": { "async": "2.1.4", - "bson": "1.0.4", + "bson": "~1.0.4", "hooks-fixed": "2.0.0", "kareem": "1.5.0", "mongodb": "2.2.31", @@ -6025,30 +26921,117 @@ "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz", "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=", "requires": { - "lodash": "4.17.4" + "lodash": "^4.14.0" + } + }, + "bson": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", + "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" + }, + "mongodb": { + "version": "2.2.31", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.31.tgz", + "integrity": "sha1-GUBEXGYeGSF7s7+CRdmFSq71SNs=", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.15", + "readable-stream": "2.2.7" + } + }, + "mongodb-core": { + "version": "2.1.15", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.15.tgz", + "integrity": "sha1-hB9TuH//9MdFgYnDXIroJ+EWl2Q=", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" } } } }, + "mongoose-slug-generator": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mongoose-slug-generator/-/mongoose-slug-generator-1.0.4.tgz", + "integrity": "sha1-pTZPLUIDeDRywjXDAtNaobINU+s=", + "requires": { + "async": "^1.5.0", + "shortid": "^2.2.4", + "speakingurl": "^7.0.0" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + } + } + }, + "mongoose-unique-validator": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mongoose-unique-validator/-/mongoose-unique-validator-2.0.2.tgz", + "integrity": "sha512-gbKFiEzWQi8wZvZFeeEkx4nCV1qWaeRoQBNm+672+h54/0u/Y8rSdNubScn/1H2ScCPO55asDow+OXq67RQDmg==", + "requires": { + "lodash.foreach": "^4.1.0", + "lodash.get": "^4.0.2" + } + }, "morgan": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.8.2.tgz", - "integrity": "sha1-eErHc05KRTqcbm6GgKkyknXItoc=", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", "requires": { - "basic-auth": "1.1.0", - "debug": "2.6.8", - "depd": "1.1.1", - "on-finished": "2.3.0", - "on-headers": "1.0.1" + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" }, "dependencies": { "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -6086,6 +27069,11 @@ "ms": "2.0.0" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, "sliced": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", @@ -6094,30 +27082,23 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, "multer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz", - "integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.1.tgz", + "integrity": "sha512-zzOLNRxzszwd+61JFuAo0fxdQfvku12aNJgnla0AQ+hHxFmfc/B7jBVuPr5Rmvu46Jze/iJrFpSOsD7afO8SDw==", "requires": { - "append-field": "0.1.0", - "busboy": "0.2.14", - "concat-stream": "1.6.0", - "mkdirp": "0.5.1", - "object-assign": "3.0.0", - "on-finished": "2.3.0", - "type-is": "1.6.15", - "xtend": "4.0.1" - }, - "dependencies": { - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" - } + "append-field": "^1.0.0", + "busboy": "^0.2.11", + "concat-stream": "^1.5.2", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.1", + "on-finished": "^2.3.0", + "type-is": "^1.6.4", + "xtend": "^4.0.0" } }, "multipipe": { @@ -6133,15 +27114,66 @@ "resolved": "https://registry.npmjs.org/muri/-/muri-1.2.2.tgz", "integrity": "sha1-YxmBMmUNsIoEzHnM0A3Tia/SYxw=" }, + "mute-stdout": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==" + }, "mute-stream": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.6.tgz", "integrity": "sha1-SJYrGeFp/R38JAs/HnMXYnu8R9s=" }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, + "nanoid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.0.1.tgz", + "integrity": "sha512-k1u2uemjIGsn25zmujKnotgniC/gxQ9sdegdezeDiKdkDW56THUMqlz3urndKCXJxA6yPzSZbXx/QCMe/pxqsA==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, "natives": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", - "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=" + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", + "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==" }, "natural-compare": { "version": "1.4.0", @@ -6153,24 +27185,39 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==" + }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "nise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.0.tgz", - "integrity": "sha512-U+Krdzhsw4losPP/Rij5UGTLQgS9gaWmXdRIbZQIQWVsUGDBo+N0m9mrY9CCEnmwssgswwydxLJUZtFfouC0gA==", + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.10.tgz", + "integrity": "sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA==", "dev": true, "requires": { - "@sinonjs/formatio": "2.0.0", - "just-extend": "1.1.27", - "lolex": "2.3.2", - "path-to-regexp": "1.7.0", - "text-encoding": "0.6.4" + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0" }, "dependencies": { + "@sinonjs/formatio": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", + "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", @@ -6183,39 +27230,150 @@ "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", "dev": true, "requires": { - "isarray": "0.0.1" + "isarray": "0.0.1" + } + } + } + }, + "nocache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", + "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "nodemon": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.6.tgz", + "integrity": "sha512-4I3YDSKXg6ltYpcnZeHompqac4E6JeAMpGm8tJnB9Y3T0ehasLa4139dJOcCrB93HHrUMsCrKtoAlXTqT5n4AQ==", + "requires": { + "chokidar": "^3.2.2", + "debug": "^3.2.6", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.0.4", + "pstree.remy": "^1.1.7", + "semver": "^5.7.1", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.3", + "update-notifier": "^4.1.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" } - } - } - }, - "nocache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz", - "integrity": "sha1-ICtIAhoMTL3i34DeFaF0Q8i0OYA=" - }, - "nodemon": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.12.0.tgz", - "integrity": "sha1-5ThUindzQKGfhVxPCHt+Uoqj/to=", - "requires": { - "chokidar": "1.7.0", - "debug": "2.6.8", - "es6-promise": "3.3.1", - "ignore-by-default": "1.0.1", - "lodash.defaults": "3.1.2", - "minimatch": "3.0.4", - "ps-tree": "1.1.0", - "touch": "3.1.0", - "undefsafe": "0.0.3", - "update-notifier": "2.2.0" - }, - "dependencies": { - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "requires": { - "ms": "2.0.0" + "is-number": "^7.0.0" } } } @@ -6225,18 +27383,18 @@ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", "requires": { - "abbrev": "1.1.0" + "abbrev": "1" } }, "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { @@ -6244,24 +27402,38 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "requires": { - "remove-trailing-separator": "1.1.0" + "remove-trailing-separator": "^1.0.1" + } + }, + "normalize-url": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", + "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + }, + "now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "requires": { + "once": "^1.3.2" } }, "npm-path": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.3.tgz", - "integrity": "sha1-Fc/04ciaONp39W9gVbJPl137K74=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", + "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", "dev": true, "requires": { - "which": "1.3.0" + "which": "^1.2.10" } }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "npm-which": { @@ -6270,9 +27442,9 @@ "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", "dev": true, "requires": { - "commander": "2.11.0", - "npm-path": "2.0.3", - "which": "1.3.0" + "commander": "^2.9.0", + "npm-path": "^2.0.2", + "which": "^1.2.10" } }, "number-is-nan": { @@ -6280,30 +27452,96 @@ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" + }, "oauth": { "version": "0.9.15", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE=" }, + "oauth-1.0a": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/oauth-1.0a/-/oauth-1.0a-2.2.6.tgz", + "integrity": "sha512-6bkxv3N4Gu5lty4viIcIAnq5GbxECviMBeKR3WX/q87SPQ8E8aursPZUtsXDnxCs787af09WPRBLqYrf/lwoYQ==" + }, "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, + "object-component": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", "requires": { - "array-each": "1.0.1", - "array-slice": "1.0.0", - "for-own": "1.0.0", - "isobject": "3.0.1" + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" }, "dependencies": { "for-own": { @@ -6311,7 +27549,7 @@ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "isobject": { @@ -6321,13 +27559,32 @@ } } }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "requires": { + "for-in": "^1.0.1" + } + } + } + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" } }, "object.pick": { @@ -6335,7 +27592,7 @@ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" }, "dependencies": { "isobject": { @@ -6345,6 +27602,25 @@ } } }, + "object.reduce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", + "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "dependencies": { + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "requires": { + "for-in": "^1.0.1" + } + } + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -6354,16 +27630,16 @@ } }, "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -6372,26 +27648,11 @@ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=" }, "ono": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/ono/-/ono-4.0.2.tgz", - "integrity": "sha512-EFXJFoeF+KkZW4lwmcPMKHp2ZU7o6CM+ccX2nPbEJKiJIdyqbIcS1v6pmNgeNJ6x4/vEYn0/8oz66qXSPnnmSQ==", - "requires": { - "format-util": "1.0.3" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/ono/-/ono-4.0.11.tgz", + "integrity": "sha512-jQ31cORBFE6td25deYeD80wxKBMj+zBmHTrVxnc6CKhx8gho6ipmWM5zj/oeoqioZ99yqBls9Z/9Nss7J26G2g==", "requires": { - "wordwrap": "0.0.3" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - } + "format-util": "^1.0.3" } }, "optionator": { @@ -6399,12 +27660,12 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "ora": { @@ -6413,10 +27674,37 @@ "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", "dev": true, "requires": { - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-spinners": "0.1.2", - "object-assign": "4.1.1" + "chalk": "^1.1.1", + "cli-cursor": "^1.0.2", + "cli-spinners": "^0.1.2", + "object-assign": "^4.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } } }, "orchestrator": { @@ -6424,9 +27712,9 @@ "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", "requires": { - "end-of-stream": "0.1.5", - "sequencify": "0.0.7", - "stream-consume": "0.1.0" + "end-of-stream": "~0.1.5", + "sequencify": "~0.0.7", + "stream-consume": "~0.1.0" } }, "ordered-read-streams": { @@ -6439,6 +27727,14 @@ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, "os-shim": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", @@ -6454,43 +27750,64 @@ "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz", "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "requires": { - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "object-assign": "4.1.1" + "graceful-fs": "^4.1.4", + "mkdirp": "^0.5.1", + "object-assign": "^4.1.0" } }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==" + }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true }, "p-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", - "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } }, "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { - "p-limit": "1.1.0" + "p-limit": "^1.1.0" } }, "p-map": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.1.1.tgz", - "integrity": "sha1-BfXkrpegaDcbwqXMhr+9vBnErno=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==" + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" }, "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", - "requires": { - "got": "6.7.1", - "registry-auth-token": "3.3.1", - "registry-url": "3.1.0", - "semver": "5.4.1" + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "pad-right": { @@ -6498,17 +27815,22 @@ "resolved": "https://registry.npmjs.org/pad-right/-/pad-right-0.2.2.tgz", "integrity": "sha1-b7ySQEXSRPKiokRQMGDTv8YAl3Q=", "requires": { - "repeat-string": "1.6.1" + "repeat-string": "^1.5.2" } }, + "page-metadata-parser": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/page-metadata-parser/-/page-metadata-parser-1.1.4.tgz", + "integrity": "sha512-TbPNw7GddbHs4c2DyYinFvh51BVsaMfdrweeylzGlg8qeuzALGxq2NF+6jbmeKc7DnU2BZRDOuWNnEjDwUSqRQ==" + }, "parse-filepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", - "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", "requires": { - "is-absolute": "0.2.6", - "map-cache": "0.2.2", - "path-root": "0.1.1" + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" } }, "parse-glob": { @@ -6516,10 +27838,10 @@ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" } }, "parse-json": { @@ -6527,25 +27849,56 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" + }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==" + }, + "parseqs": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", + "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "requires": { + "better-assert": "~1.0.0" + } + }, + "parseuri": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", + "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "requires": { + "better-assert": "~1.0.0" + } + }, "parseurl": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.1.tgz", - "integrity": "sha1-yKuMkiO6NIiKpkopeyiFO+wY2lY=" + "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", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, "passport": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.0.tgz", "integrity": "sha1-xQlWkTR71a07XhgCOMORTRbwWBE=", "requires": { - "passport-strategy": "1.0.0", + "passport-strategy": "1.x.x", "pause": "0.0.1" } }, @@ -6562,8 +27915,8 @@ "resolved": "https://registry.npmjs.org/passport-oauth/-/passport-oauth-1.0.0.tgz", "integrity": "sha1-kK/2M4dUDwIImvKM2tOep/gNd98=", "requires": { - "passport-oauth1": "1.1.0", - "passport-oauth2": "1.4.0" + "passport-oauth1": "1.x.x", + "passport-oauth2": "1.x.x" } }, "passport-oauth1": { @@ -6571,20 +27924,21 @@ "resolved": "https://registry.npmjs.org/passport-oauth1/-/passport-oauth1-1.1.0.tgz", "integrity": "sha1-p96YiiEfnPRoc3cTDqdN8ycwyRg=", "requires": { - "oauth": "0.9.15", - "passport-strategy": "1.0.0", - "utils-merge": "1.0.0" + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "utils-merge": "1.x.x" } }, "passport-oauth2": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.4.0.tgz", - "integrity": "sha1-9i+BWDy+EmCb585vFguTlaJ7hq0=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz", + "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==", "requires": { - "oauth": "0.9.15", - "passport-strategy": "1.0.0", - "uid2": "0.0.3", - "utils-merge": "1.0.0" + "base64url": "3.x.x", + "oauth": "0.9.x", + "passport-strategy": "1.x.x", + "uid2": "0.0.x", + "utils-merge": "1.x.x" } }, "passport-strategy": { @@ -6592,12 +27946,17 @@ "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-is-absolute": { @@ -6613,19 +27972,20 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true }, "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", "requires": { - "path-root-regex": "0.1.2" + "path-root-regex": "^0.1.0" } }, "path-root-regex": { @@ -6643,7 +28003,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "requires": { - "pify": "2.3.0" + "pify": "^2.0.0" }, "dependencies": { "pify": { @@ -6663,19 +28023,16 @@ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "requires": { - "through": "2.3.8" - } - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", @@ -6691,36 +28048,36 @@ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "requires": { - "find-up": "1.1.2" + "find-up": "^2.1.0" } }, - "platform": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz", - "integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=" - }, "pluralize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz", "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=" }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "preserve": { "version": "0.2.0", @@ -6733,8 +28090,8 @@ "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==", "dev": true, "requires": { - "ansi-regex": "3.0.0", - "ansi-styles": "3.2.0" + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" }, "dependencies": { "ansi-regex": { @@ -6742,15 +28099,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.0" - } } } }, @@ -6760,35 +28108,32 @@ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" }, "private": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", - "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=" + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, "proxy-addr": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz", - "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=", - "requires": { - "forwarded": "0.1.0", - "ipaddr.js": "1.4.0" - } - }, - "ps-tree": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", - "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", "requires": { - "event-stream": "3.3.4" + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" } }, "pseudomap": { @@ -6796,91 +28141,107 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=" + "psl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" }, - "raccoon": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/raccoon/-/raccoon-0.2.8.tgz", - "integrity": "sha1-gKcGlDWTliBDZv031RR72gn1ayk=", + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "requires": { - "async": "2.1.5", - "bluebird": "3.4.7", - "redis": "2.6.5", - "underscore": "1.8.3" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" }, "dependencies": { - "async": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz", - "integrity": "sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=", - "requires": { - "lodash": "4.17.4" - } - }, - "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" - }, - "redis": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.6.5.tgz", - "integrity": "sha1-h8Hv9KSJ+Utwhx89CLaYjyOpVoc=", + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { - "double-ended-queue": "2.1.0-0", - "redis-commands": "1.3.1", - "redis-parser": "2.6.0" + "once": "^1.4.0" } } } }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "pupa": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", + "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", + "requires": { + "escape-goat": "^2.0.0" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "qs-mongodb": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/qs-mongodb/-/qs-mongodb-0.1.0.tgz", + "integrity": "sha1-n+EaJ+F3eEjxBLNN69bj2hPLiFs=", "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "qs": "~2.3.3" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "1.1.5" - } - } - } + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=" + } + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=" + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" }, "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "1.1.5" - } + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" } } }, @@ -6900,9 +28261,9 @@ } }, "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { "version": "2.2.0", @@ -6915,21 +28276,14 @@ } }, "rc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", - "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" } }, "read-pkg": { @@ -6937,9 +28291,9 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, "read-pkg-up": { @@ -6947,43 +28301,303 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "2.0.0" - } - } + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "recaptcha2": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/recaptcha2/-/recaptcha2-1.3.3.tgz", + "integrity": "sha512-HgpvAmukTQW1UyZxM7PT/yLFayAN6rjTvYH13z/Ci69KfcOtv3BskRGBu7in+npzUG9XSxYAfRDtn6+p6p7tAw==", "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.3", - "set-immediate-shim": "1.0.1" + "request": "2.x" } }, "rechoir": { @@ -6991,7 +28605,7 @@ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "requires": { - "resolve": "1.4.0" + "resolve": "^1.1.6" } }, "recursive-iterator": { @@ -6999,49 +28613,37 @@ "resolved": "https://registry.npmjs.org/recursive-iterator/-/recursive-iterator-2.0.3.tgz", "integrity": "sha1-0ODSx+eoMQnXMJHPBD/FCeWnbcM=" }, - "redis": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "reduce": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/reduce/-/reduce-1.0.2.tgz", + "integrity": "sha512-xX7Fxke/oHO5IfZSk77lvPa/7bjMh9BuCk4OOoX5XTXrM7s0Z+MkPfSDfz0q7r91BhhGSs8gii/VEN/7zhCPpQ==", "requires": { - "double-ended-queue": "2.1.0-0", - "redis-commands": "1.3.1", - "redis-parser": "2.6.0" + "object-keys": "^1.1.0" } }, - "redis-commands": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz", - "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs=" - }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=" - }, "referrer-policy": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.1.0.tgz", - "integrity": "sha1-NXdOtzW/UPtsB46DM0tHI1AgfXk=" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", + "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" }, "regenerate": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", - "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" }, "regenerator-runtime": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", - "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "regenerator-transform": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "requires": { - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "private": "0.1.7" + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" } }, "regex-cache": { @@ -7049,7 +28651,16 @@ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "requires": { - "is-equal-shallow": "0.1.3" + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" } }, "regexp-clone": { @@ -7062,26 +28673,25 @@ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "requires": { - "regenerate": "1.3.2", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } }, "registry-auth-token": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", - "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "requires": { - "rc": "1.2.1", - "safe-buffer": "5.1.1" + "rc": "^1.2.8" } }, "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", "requires": { - "rc": "1.2.1" + "rc": "^1.2.8" } }, "regjsgen": { @@ -7094,7 +28704,7 @@ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" }, "dependencies": { "jsesc": { @@ -7104,15 +28714,34 @@ } } }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "requires": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "requires": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + } + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" }, "repeat-string": { "version": "1.6.1", @@ -7124,7 +28753,7 @@ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "replace-ext": { @@ -7132,53 +28761,81 @@ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" }, - "request": { - "version": "2.79.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", - "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "replace-homedir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", + "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.11.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.17", - "oauth-sign": "0.8.2", - "qs": "6.3.2", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.4.3", - "uuid": "3.1.0" + "homedir-polyfill": "^1.0.1", + "is-absolute": "^1.0.0", + "remove-trailing-separator": "^1.1.0" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" }, "dependencies": { - "qs": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", - "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=" + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } } } }, - "require-from-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.1.tgz", - "integrity": "sha1-xUUjPp19pmFunVmt+zn8n1iGdv8=", - "dev": true + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "requires": { + "lodash": "^4.17.15" + } }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } } }, "require_optional": { @@ -7186,8 +28843,8 @@ "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", "requires": { - "resolve-from": "2.0.0", - "semver": "5.4.1" + "resolve-from": "^2.0.0", + "semver": "^5.1.0" }, "dependencies": { "resolve-from": { @@ -7197,12 +28854,42 @@ } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "require-uncached": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "requires": { + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "resolve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.6" } }, "resolve-dir": { @@ -7210,8 +28897,8 @@ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", "requires": { - "expand-tilde": "1.2.2", - "global-modules": "0.2.3" + "expand-tilde": "^1.2.2", + "global-modules": "^0.2.3" } }, "resolve-from": { @@ -7219,28 +28906,40 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "requires": { + "value-or-function": "^3.0.0" + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "requires": { + "lowercase-keys": "^1.0.0" + } + }, "restore-cursor": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" + "exit-hook": "^1.0.0", + "onetime": "^1.0.0" } }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "optional": true, - "requires": { - "align-text": "0.1.4" - } + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, "right-pad": { "version": "1.0.1", @@ -7248,11 +28947,11 @@ "integrity": "sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=" }, "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "requires": { - "glob": "7.1.2" + "glob": "^7.1.3" } }, "run-async": { @@ -7260,7 +28959,7 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "requires": { - "is-promise": "2.1.0" + "is-promise": "^2.1.0" } }, "run-sequence": { @@ -7268,8 +28967,32 @@ "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-2.1.0.tgz", "integrity": "sha1-FJ2gElFvIdz3nbbcmaKpVgNjGyE=", "requires": { - "chalk": "1.1.3", - "gulp-util": "3.0.8" + "chalk": "^1.1.3", + "gulp-util": "^3.0.8" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + } } }, "rx": { @@ -7287,13 +29010,13 @@ "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "requires": { - "rx-lite": "4.0.8" + "rx-lite": "*" } }, "rxjs": { - "version": "5.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.5.tgz", - "integrity": "sha512-D/MfQnPMBk8P8gfwGxvCkuaWBcG58W7dUMT//URPoYzIbDEKT0GezdirkK5whMgKFBATfCoTpxO8bJQGJ04W5A==", + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", "dev": true, "requires": { "symbol-observable": "1.0.1" @@ -7308,9 +29031,22 @@ } }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "samsam": { "version": "1.3.0", @@ -7318,22 +29054,54 @@ "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", "dev": true }, + "saslprep": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.2.tgz", + "integrity": "sha512-4cDsYuAjXssUSjxHKRe4DTZC0agDwsCqcMqtJAQPzC74nJ7LfAJflAtC1Zed5hMzEQKj82d3tuzqdGNRsLJ4Gw==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, + "saxes": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-4.0.2.tgz", + "integrity": "sha512-EZOTeQ4bgkOaGCDaTKux+LaRNcLNbdbvMH7R3/yjEEULPEmqvkFbFub6DJhJTub2iGMT93CfpZ5LTdKZmAbVeQ==", + "requires": { + "xmlchars": "^2.2.0" + } + }, "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "semver-greatest-satisfied-range": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", + "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", "requires": { - "semver": "5.4.1" + "sver-compat": "^1.5.0" } }, "semver-regex": { @@ -7342,32 +29110,61 @@ "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=" }, "send": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/send/-/send-0.15.4.tgz", - "integrity": "sha1-mF+qPihLAnPHkzZKNcZze9k5Bbk=", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "requires": { - "debug": "2.6.8", - "depd": "1.1.1", - "destroy": "1.0.4", - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "etag": "1.8.0", - "fresh": "0.5.0", - "http-errors": "1.6.2", - "mime": "1.3.4", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.3.1" + "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.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" }, "dependencies": { "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" } } }, @@ -7376,13 +29173,13 @@ "resolved": "https://registry.npmjs.org/sendgrid/-/sendgrid-5.2.3.tgz", "integrity": "sha512-FD7oR9TbJFUew1p0Vw9JX0wBetDyq634LzylSXz4n9+hwaf+6a9dNloZl8CcjpsX4NuEc3HJanTN4GjDwNyi4A==", "requires": { - "async.ensureasync": "0.5.2", - "async.queue": "0.5.2", - "bottleneck": "1.16.0", - "debug": "2.6.9", - "lodash.chunk": "4.2.0", - "mailparser": "0.6.2", - "sendgrid-rest": "2.4.0" + "async.ensureasync": "^0.5.2", + "async.queue": "^0.5.2", + "bottleneck": "^1.12.0", + "debug": "^2.2.0", + "lodash.chunk": "^4.2.0", + "mailparser": "^0.6.1", + "sendgrid-rest": "^2.3.0" }, "dependencies": { "debug": { @@ -7392,6 +29189,11 @@ "requires": { "ms": "2.0.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -7406,32 +29208,60 @@ "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=" }, "serve-static": { - "version": "1.12.4", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.4.tgz", - "integrity": "sha1-m2qpjutyU8Tu3Ewfb9vKYJkBqWE=", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "requires": { - "encodeurl": "1.0.1", - "escape-html": "1.0.3", - "parseurl": "1.3.1", - "send": "0.15.4" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "dependencies": { + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + } } }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } }, "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + "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", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -7444,9 +29274,17 @@ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.6.tgz", "integrity": "sha1-N5zM+1a5HIYB5HkzVutTgpJN6a0=", "requires": { - "glob": "7.1.2", - "interpret": "1.0.3", - "rechoir": "0.6.2" + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "shortid": { + "version": "2.2.14", + "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.14.tgz", + "integrity": "sha512-4UnZgr9gDdA1kaKj/38IiudfC3KHKhDc1zi/HSxd9FQDR0VLwH3/y79tZJLsVYPsJgIjeHjqIWaWVRJUj9qZOQ==", + "requires": { + "nanoid": "^2.0.0" } }, "sigmund": { @@ -7460,47 +29298,24 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, "sinon": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.4.2.tgz", - "integrity": "sha512-cpOHpnRyY3Dk9dTHBYMfVBB0HUCSKIpxW07X6OGW2NiYPovs4AkcL8Q8MzecbAROjbfRA9esJCmlZgikxDz7DA==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.5.0.tgz", + "integrity": "sha512-trdx+mB0VBBgoYucy6a9L7/jfQOmvGeaKZT4OOJ+lPAtI8623xyGr8wLiE4eojzBS8G9yXbhx42GHUOVLr4X2w==", "dev": true, "requires": { - "@sinonjs/formatio": "2.0.0", - "diff": "3.2.0", - "lodash.get": "4.4.2", - "lolex": "2.3.2", - "nise": "1.3.0", - "supports-color": "5.3.0", - "type-detect": "4.0.8" - }, - "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - } + "@sinonjs/formatio": "^2.0.0", + "diff": "^3.1.0", + "lodash.get": "^4.4.2", + "lolex": "^2.2.0", + "nise": "^1.2.0", + "supports-color": "^5.1.0", + "type-detect": "^4.0.5" } }, "sinon-mongoose": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/sinon-mongoose/-/sinon-mongoose-2.0.2.tgz", - "integrity": "sha1-ZYyuciZXkW0uHmUrApo28ehHrPU=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/sinon-mongoose/-/sinon-mongoose-2.2.1.tgz", + "integrity": "sha512-Z+E3924Bvy+Gre9bKT3IyQuXOtw6ZI+4VoC49X2pQoOf+wrC0yCi0jd+FtVD+xsRvSKcR+GscPbFaGm1ZkPNDg==", "dev": true }, "slash": { @@ -7509,21 +29324,263 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" }, "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", + "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "requires": { + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + } + } }, "sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" }, + "slug": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/slug/-/slug-0.9.4.tgz", + "integrity": "sha512-3YHq0TeJ4+AIFbJm+4UWSQs5A1mmeWOTQqydW3OoPmQfNKxlO96NDRTIrp+TBkmvEsEFrd+Z/LXw8OD/6OlZ5g==", + "requires": { + "unicode": ">= 0.3.1" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + } + }, "sntp": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", "requires": { - "hoek": "2.16.3" + "hoek": "2.x.x" + } + }, + "socket.io": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", + "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "requires": { + "debug": "~4.1.0", + "engine.io": "~3.4.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.3.0", + "socket.io-parser": "~3.4.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" + }, + "socket.io-client": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", + "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "engine.io-client": "~3.4.0", + "has-binary2": "~1.0.2", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + }, + "socket.io-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", + "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~3.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + } + } + }, + "socket.io-parser": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.0.tgz", + "integrity": "sha512-/G/VOI+3DBp0+DJKW4KesGnQkQPFmUCbA/oO2QGT6CWxU7hLGWqU3tyuzeSK/dqcyeHsQg1vTe9jiZI8GU9SCQ==", + "requires": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" + } } }, "source-map": { @@ -7532,67 +29589,92 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" }, "source-map-resolve": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", - "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "requires": { - "atob": "1.1.3", - "resolve-url": "0.2.1", - "source-map-url": "0.3.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, "source-map-support": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.17.tgz", - "integrity": "sha512-30c1Ch8FSjV0FwC253iftbbj0dU/OXoSg1LAEGZJUlGgjTNj6cu+DVqJWWIZJY5RXLWV4eFtR+4ouo0VIOYOTg==", + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "requires": { - "source-map": "0.5.7" + "source-map": "^0.5.6" } }, "source-map-url": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", - "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, "sparkles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", - "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", + "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==" + }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } }, "spawn-sync": { "version": "1.0.15", "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz", "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", "requires": { - "concat-stream": "1.6.0", - "os-shim": "0.1.3" + "concat-stream": "^1.4.7", + "os-shim": "^0.1.2" } }, "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "requires": { - "spdx-license-ids": "1.2.2" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + }, "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } }, "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==" }, - "split": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", - "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "speakingurl": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-7.0.0.tgz", + "integrity": "sha1-Cjkoc6+DutWUVlzj3LQzLVGHqws=" + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "requires": { - "through": "2.3.8" + "extend-shallow": "^3.0.0" } }, "sprintf-js": { @@ -7601,25 +29683,19 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" } }, "stack-trace": { @@ -7628,28 +29704,54 @@ "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, "staged-git-files": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-0.0.4.tgz", - "integrity": "sha1-15fhtVHKemOd7AI33G60u5vhfTU=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-1.0.0.tgz", + "integrity": "sha1-zbhHg3wfzFLAioctSIPMCHdmioA=", "dev": true }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" - }, - "stream-combiner": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", - "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "requires": { - "duplexer": "0.1.1" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + } } }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + }, "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=" + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz", + "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==" + }, + "stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==" + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, "stream-to-observable": { "version": "0.2.0", @@ -7657,7 +29759,7 @@ "integrity": "sha1-WdbqOT2HwsDdrBCqDVYbxrpvDhA=", "dev": true, "requires": { - "any-observable": "0.2.0" + "any-observable": "^0.2.0" } }, "streamsearch": { @@ -7665,46 +29767,46 @@ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "stringify-object": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.1.tgz", - "integrity": "sha512-jPcQYw/52HUPP8uOE4kkjxl5bB9LfHkKCTptIk3qw7ozP5XMIMlHMLjt00GGSwW6DJAf/njY5EU6Vpwl4LlBKQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", "dev": true, "requires": { - "get-own-enumerable-property-symbols": "2.0.1", - "is-obj": "1.0.1", - "is-regexp": "1.0.0" + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" } }, "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==" }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -7720,7 +29822,8 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true }, "strip-indent": { "version": "2.0.0", @@ -7734,52 +29837,39 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "stripe": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-5.5.0.tgz", - "integrity": "sha512-oy8xNoxv5/4eFsn+W/0KQvG9St7x/xM8TbOIW2prBLd2+zo+2y2V9iyqcNt6B14efcOE2YeCR1s5yw+1cqa2VQ==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/stripe/-/stripe-5.10.0.tgz", + "integrity": "sha512-AUDmXfNAAY/oOfW87HPO4bDzNWJp8iQd0blVWwwEgPxO1DmEC//foI0C9rhr2ZNsuF6kLypPfNtGB9Uf+RCQzQ==", "requires": { - "bluebird": "3.5.0", - "lodash.isplainobject": "4.0.6", - "qs": "6.5.1", - "safe-buffer": "5.1.1" - }, - "dependencies": { - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" - } + "lodash.isplainobject": "^4.0.6", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1" } }, "superagent": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.6.0.tgz", - "integrity": "sha512-oWsu4mboo8sVxagp4bNwZIR1rUmypeAJDmNIwT9mF4k06hSu6P92aOjEWLaIj7vsX3fOUp+cRH/04tao+q5Q7A==", - "requires": { - "component-emitter": "1.2.1", - "cookiejar": "2.1.1", - "debug": "2.6.8", - "extend": "3.0.1", - "form-data": "2.1.4", - "formidable": "1.1.1", - "methods": "1.1.2", - "mime": "1.4.0", - "qs": "6.4.0", - "readable-stream": "2.3.3" + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "requires": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" }, "dependencies": { "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } - }, - "mime": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.0.tgz", - "integrity": "sha512-n9ChLv77+QQEapYz8lV+rIZAW3HhAPW2CXnzb1GN5uMkuczshwvkW7XPsbzU0ZQN3sP47Er2KVkp2p3KyqZKSQ==" } } }, @@ -7788,8 +29878,8 @@ "resolved": "https://registry.npmjs.org/supertest/-/supertest-3.0.0.tgz", "integrity": "sha1-jUu2j9GDDuBwM7HFpamkAhyWUpY=", "requires": { - "methods": "1.1.2", - "superagent": "3.6.0" + "methods": "~1.1.2", + "superagent": "^3.0.0" } }, "supertest-as-promised": { @@ -7797,49 +29887,397 @@ "resolved": "https://registry.npmjs.org/supertest-as-promised/-/supertest-as-promised-4.0.2.tgz", "integrity": "sha1-BGTyvSVlaNSlm86EJpwFSPaHnxo=", "requires": { - "bluebird": "3.5.0", - "methods": "1.1.2" + "bluebird": "^3.3.1", + "methods": "^1.1.1" } }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } }, - "swagger-jsdoc": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-1.9.7.tgz", - "integrity": "sha1-enYdTX70pUv0V86lxn7DFruC+Lk=", + "sver-compat": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", + "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", "requires": { - "chokidar": "1.7.0", - "commander": "2.11.0", - "doctrine": "2.0.0", - "glob": "7.1.2", - "js-yaml": "3.10.0", - "recursive-iterator": "2.0.3", - "swagger-parser": "3.4.2" + "es6-iterator": "^2.0.1", + "es6-symbol": "^3.1.1" + } + }, + "swagger-jsdoc": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/swagger-jsdoc/-/swagger-jsdoc-1.10.3.tgz", + "integrity": "sha512-ol8QBX8wxm4sik+W0uiMcLNxdB+cKhtsXy3LMbnNe8KabdpMH9wRFQBdP7LtrCR6kx9zjWvqMTLpnUv0zJjFlg==", + "requires": { + "chokidar": "^2.0.3", + "commander": "^2.11.0", + "doctrine": "^2.0.0", + "glob": "^7.1.2", + "js-yaml": "^3.8.4", + "recursive-iterator": "^2.0.3", + "swagger-parser": "^3.4.1" }, "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz", + "integrity": "sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==", + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", + "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" }, "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" } } }, "swagger-methods": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/swagger-methods/-/swagger-methods-1.0.0.tgz", - "integrity": "sha1-s5x3lX0wWmU1wKHgFQgRhbmdYfw=" + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/swagger-methods/-/swagger-methods-1.0.8.tgz", + "integrity": "sha512-G6baCwuHA+C5jf4FNOrosE4XlmGsdjbOjdBK4yuiDDj/ro9uR4Srj3OR84oQMT8F3qKp00tYNv0YN730oTHPZA==" }, "swagger-node-express": { "version": "2.1.3", @@ -7863,20 +30301,28 @@ "resolved": "https://registry.npmjs.org/swagger-parser/-/swagger-parser-3.4.2.tgz", "integrity": "sha512-himpIkA50AjTvrgtz0PPbzwWoTjj3F3ye/y1PcW/514YEp1A3IhAcJFkkEu7b1zHnSIthnzxC8aTy+XZG0D+iA==", "requires": { - "call-me-maybe": "1.0.1", - "debug": "3.0.1", - "es6-promise": "4.1.1", - "json-schema-ref-parser": "1.4.1", - "ono": "4.0.2", - "swagger-methods": "1.0.0", + "call-me-maybe": "^1.0.1", + "debug": "^3.0.0", + "es6-promise": "^4.1.1", + "json-schema-ref-parser": "^1.4.1", + "ono": "^4.0.2", + "swagger-methods": "^1.0.0", "swagger-schema-official": "2.0.0-bab6bed", - "z-schema": "3.18.4" + "z-schema": "^3.16.1" }, "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, "es6-promise": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz", - "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==" + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" } } }, @@ -7891,28 +30337,24 @@ "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", "dev": true }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, "table": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.1.tgz", - "integrity": "sha1-qBFsEz+sLGH0pCCrbN9cTWHw5DU=", - "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.4", - "slice-ansi": "0.0.4", - "string-width": "2.1.1" + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", + "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", + "requires": { + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" }, "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -7928,8 +30370,8 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" } }, "strip-ansi": { @@ -7937,24 +30379,15 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } }, "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", - "requires": { - "execa": "0.7.0" - } - }, - "text-encoding": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", - "dev": true + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==" }, "text-table": { "version": "0.2.0", @@ -7967,12 +30400,21 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", "requires": { - "readable-stream": "2.3.3", - "xtend": "4.0.1" + "through2": "~2.0.0", + "xtend": "~4.0.0" } }, "tildify": { @@ -7980,7 +30422,7 @@ "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", "requires": { - "os-homedir": "1.0.2" + "os-homedir": "^1.0.0" } }, "time-stamp": { @@ -7988,18 +30430,13 @@ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, "timers-ext": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz", - "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=", + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", "requires": { - "es5-ext": "0.10.30", - "next-tick": "1.0.0" + "es5-ext": "~0.10.46", + "next-tick": "1" } }, "tmp": { @@ -8007,36 +30444,108 @@ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.29.tgz", "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.1" + } + }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" } }, + "to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" }, - "topo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz", - "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=", + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==" + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", "requires": { - "hoek": "2.16.3" + "through2": "^2.0.3" } }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", "requires": { - "nopt": "1.0.10" + "nopt": "~1.0.10" } }, "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "requires": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", "requires": { - "punycode": "1.4.1" + "punycode": "^2.1.1" } }, "trim-right": { @@ -8044,42 +30553,58 @@ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" }, - "tryit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=" + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" }, "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=" + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "optional": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "twitter-lite": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/twitter-lite/-/twitter-lite-0.13.0.tgz", + "integrity": "sha512-UQxOqiZIx6BbWMNXrFhDThHf0RYuAWe02+0wHbsww61iIPeJdaakM+HJJlf8QKzIyu8q6JCZ4K9vpd55sg0V7g==", + "requires": { + "cross-fetch": "^3.0.0", + "oauth-1.0a": "^2.2.4" + } }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "type-detect": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", - "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=" + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" }, "type-is": { - "version": "1.6.15", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", - "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "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.17" + "mime-types": "~2.1.18" } }, "typedarray": { @@ -8087,23 +30612,38 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.8.0.tgz", + "integrity": "sha512-ugNSTT8ierCsDHso2jkBHXYrU8Y5/fY2ZUprfrJUiD7YpuFvV4jODLFmb3h4btQjqr5Nh4TX4XtgDfCU1WdioQ==", "optional": true, "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" + "commander": "~2.20.3", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "optional": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + } } }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "optional": true - }, "uid2": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", @@ -8115,31 +30655,81 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" }, "undefsafe": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-0.0.3.tgz", - "integrity": "sha1-7Mo6A+VrmvFzhbqsgSrIO5lKli8=" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", + "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==", + "requires": { + "debug": "^2.2.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } }, - "underscore": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", - "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + "undertaker": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", + "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", + "requires": { + "arr-flatten": "^1.0.1", + "arr-map": "^2.0.0", + "bach": "^1.0.0", + "collection-map": "^1.0.0", + "es6-weak-map": "^2.0.1", + "last-run": "^1.1.0", + "object.defaults": "^1.0.0", + "object.reduce": "^1.0.0", + "undertaker-registry": "^1.0.0" + } + }, + "undertaker-registry": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=" + }, + "unicode": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/unicode/-/unicode-12.1.0.tgz", + "integrity": "sha512-Ty6+Ew21DiYTWLYtd05RF/X4c1ekOvOgANyHbBj0h3MaXpfaGr2Rdmc0hMFuGQLyPLb9cU4ArNxl0bTF5HSzXw==" }, "unicons": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/unicons/-/unicons-0.0.3.tgz", "integrity": "sha1-bmp6Gm6uuwHKPYsSrZaHJ56rpSQ=" }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, "unique-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=" }, "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "requires": { - "crypto-random-string": "1.0.0" + "crypto-random-string": "^2.0.0" } }, "unpipe": { @@ -8147,24 +30737,136 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==" }, "update-notifier": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.2.0.tgz", - "integrity": "sha1-G1g3z5DAc22IYncytmHBOPht5y8=", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz", + "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==", + "requires": { + "boxen": "^4.2.0", + "chalk": "^3.0.0", + "configstore": "^5.0.1", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.1", + "is-npm": "^4.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "pupa": "^2.0.1", + "semver-diff": "^3.1.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "requires": { + "ci-info": "^2.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "requires": { - "boxen": "1.2.1", - "chalk": "1.1.3", - "configstore": "3.1.1", - "import-lazy": "2.1.0", - "is-npm": "1.0.0", - "latest-version": "3.1.0", - "semver-diff": "2.1.0", - "xdg-basedir": "3.0.0" + "punycode": "^2.1.0" } }, "urix": { @@ -8189,13 +30891,18 @@ } }, "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", "requires": { - "prepend-http": "1.0.4" + "prepend-http": "^2.0.0" } }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, "user-home": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", @@ -8212,25 +30919,25 @@ "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" }, "uue": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/uue/-/uue-3.1.1.tgz", - "integrity": "sha512-MaT3l62tAqFCApEFBWyFF5e4e7CniWupCknKSf2hWyvxZXb7PMglHa5fy4xgeopvmDkIuUqUOtXFxWHWbL/pkw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/uue/-/uue-3.1.2.tgz", + "integrity": "sha512-axKLXVqwtdI/czrjG0X8hyV1KLgeWx8F4KvSbvVCnS+RUvsQMGRjx0kfuZDXXqj0LYvVJmx3B9kWlKtEdRrJLg==", "requires": { - "escape-string-regexp": "1.0.5", - "extend": "3.0.1" + "escape-string-regexp": "~1.0.5", + "extend": "~3.0.0" } }, "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8flags": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "requires": { - "user-home": "1.1.1" + "user-home": "^1.1.1" } }, "validate-commit-msg": { @@ -8238,46 +30945,44 @@ "resolved": "https://registry.npmjs.org/validate-commit-msg/-/validate-commit-msg-2.14.0.tgz", "integrity": "sha1-5Tg2kQEsuycNzAvCpO/+vhSJDqw=", "requires": { - "conventional-commit-types": "2.2.0", - "find-parent-dir": "0.3.0", + "conventional-commit-types": "^2.0.0", + "find-parent-dir": "^0.3.0", "findup": "0.1.5", "semver-regex": "1.0.0" } }, "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, "validator": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", - "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==" + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" + }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=" }, "vary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.1.tgz", - "integrity": "sha1-Z1Neu2lMHVIldFeYRmUyP1h+jTc=" + "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", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - } + "extsprintf": "^1.2.0" } }, "vinyl": { @@ -8285,8 +30990,8 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", + "clone": "^1.0.0", + "clone-stats": "^0.0.1", "replace-ext": "0.0.1" } }, @@ -8295,14 +31000,14 @@ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", "requires": { - "defaults": "1.0.3", - "glob-stream": "3.1.18", - "glob-watcher": "0.0.6", - "graceful-fs": "3.0.11", - "mkdirp": "0.5.1", - "strip-bom": "1.0.0", - "through2": "0.6.5", - "vinyl": "0.4.6" + "defaults": "^1.0.0", + "glob-stream": "^3.1.5", + "glob-watcher": "^0.0.6", + "graceful-fs": "^3.0.0", + "mkdirp": "^0.5.0", + "strip-bom": "^1.0.0", + "through2": "^0.6.1", + "vinyl": "^0.4.0" }, "dependencies": { "clone": { @@ -8315,7 +31020,7 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", "requires": { - "natives": "1.1.0" + "natives": "^1.1.0" } }, "isarray": { @@ -8328,10 +31033,10 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -8344,8 +31049,8 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", "requires": { - "first-chunk-stream": "1.0.0", - "is-utf8": "0.2.1" + "first-chunk-stream": "^1.0.0", + "is-utf8": "^0.2.0" } }, "through2": { @@ -8353,8 +31058,8 @@ "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" } }, "vinyl": { @@ -8362,8 +31067,52 @@ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" + "clone": "^0.2.0", + "clone-stats": "^0.0.1" + } + } + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" } } } @@ -8373,42 +31122,130 @@ "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", "requires": { - "source-map": "0.5.7" + "source-map": "^0.5.1" + } + }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==" + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "requires": { + "iconv-lite": "0.4.24" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + }, + "whatwg-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.0.0.tgz", + "integrity": "sha512-41ou2Dugpij8/LPO5Pq64K5q++MnRCBpEHvQr26/mArEKTkCV5aoXIqyhuYtE0pkqScXwhf2JP57rkRTYM29lQ==", + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.0", + "webidl-conversions": "^5.0.0" } }, "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, - "widest-line": { + "which-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", - "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "requires": { - "string-width": "1.0.2" + "string-width": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "optional": true - }, "winston": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/winston/-/winston-2.3.1.tgz", "integrity": "sha1-C0hCDZeMAYBM8CMLZIhhWYIloRk=", "requires": { - "async": "1.0.0", - "colors": "1.0.3", - "cycle": "1.0.3", - "eyes": "0.1.8", - "isstream": "0.1.2", - "stack-trace": "0.0.10" + "async": "~1.0.0", + "colors": "1.0.x", + "cycle": "1.0.x", + "eyes": "0.1.x", + "isstream": "0.1.x", + "stack-trace": "0.0.x" }, "dependencies": { "async": { @@ -8433,6 +31270,15 @@ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -8443,85 +31289,188 @@ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "signal-exit": "3.0.2" + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, + "ws": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", + "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==" + }, "x-xss-protection": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.0.0.tgz", - "integrity": "sha1-iYr7k4abJGYc+cUvnujbjtB2Tdk=" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", + "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==" }, "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" + }, + "xml-name-validator": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, "xml2js": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.17.tgz", - "integrity": "sha1-F76T6q4/O3eTWceVtBlwWogX6Gg=", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", "requires": { - "sax": "1.2.1", - "xmlbuilder": "4.2.1" + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" } }, "xmlbuilder": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-4.2.1.tgz", - "integrity": "sha1-qlijBBoGb5DqoWwvU4n/GfP0YaU=", - "requires": { - "lodash": "4.17.4" - } + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, + "xmlhttprequest-ssl": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", + "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "optional": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz", + "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==", + "requires": { + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "5.0.0-security.0" }, "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "optional": true + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } } } }, + "yargs-parser": { + "version": "5.0.0-security.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz", + "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==", + "requires": { + "camelcase": "^3.0.0", + "object.assign": "^4.1.0" + } + }, + "yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" + }, "z-schema": { - "version": "3.18.4", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz", - "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==", - "requires": { - "commander": "2.11.0", - "lodash.get": "4.4.2", - "lodash.isequal": "4.5.0", - "validator": "8.2.0" + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.25.1.tgz", + "integrity": "sha512-7tDlwhrBG+oYFdXNOjILSurpfQyuVgkRe3hB2q8TEssamDHB7BbLWYkYO98nTn0FibfdFroFKDjndbgufAgS/Q==", + "requires": { + "commander": "^2.7.1", + "core-js": "^2.5.7", + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^10.0.0" } } } diff --git a/package.json b/package.json index 75b5a6a7..e1d0b8b0 100644 --- a/package.json +++ b/package.json @@ -6,24 +6,23 @@ "main": "index.js", "private": false, "engines": { - "node": "6.11.1", - "npm": "5.5.1" + "node": "10.19.0", + "npm": "^6.13.4" }, "scripts": { - "launch": "npm run build && node dist/index.js", - "start": "gulp serve", - "staging-deploy": "git push staging develop:master", - "deploy": "git push production master:master", - "start:debug": "cross-env DEBUG=software-engineering-daily-api:* npm run start", "build": "gulp", + "launch": "npm run build && node dist/index.js", + "migrate": "./node_modules/.bin/migrate up --compiler js:babel-register", "lint": "esw *.js server config --color", "lint:watch": "npm run lint -- --watch", "precommit": "lint-staged", + "report-coverage": "coveralls < ./coverage/lcov.info", + "start": "gulp serve", + "start:debug": "cross-env DEBUG=software-engineering-daily-api:* npm run start", "test": "cross-env NODE_ENV=test ./node_modules/.bin/mocha --ui bdd --reporter spec --colors --compilers js:babel-core/register --require babel-polyfill server/tests --recursive", "test:watch": "npm run test -- --watch", "test:coverage": "cross-env NODE_ENV=test ./node_modules/.bin/istanbul cover _mocha -- --ui bdd --reporter spec --colors --compilers js:babel-core/register --require babel-polyfill server/tests --recursive", - "test:check-coverage": "npm run test:coverage && istanbul check-coverage", - "report-coverage": "coveralls < ./coverage/lcov.info" + "test:check-coverage": "npm run test:coverage && istanbul check-coverage" }, "lint-staged": { "*.js": [ @@ -50,8 +49,11 @@ ], "dependencies": { "@sendgrid/mail": "^6.1.4", + "@sentry/node": "^5.17.0", + "algoliasearch": "^3.35.1", + "async": "^3.1.1", "aws-sdk": "^2.150.0", - "axios": "^0.17.1", + "axios": "^0.19.0", "babel-cli": "6.26.0", "babel-core": "6.26.0", "babel-plugin-add-module-exports": "0.2.1", @@ -66,6 +68,7 @@ "cookie-parser": "1.4.3", "cors": "2.8.4", "coveralls": "2.13.1", + "cron": "1.8.2", "cross-env": "5.0.5", "cz-conventional-changelog": "2.0.0", "debug": "3.0.1", @@ -75,40 +78,56 @@ "eslint-config-airbnb-base": "12.0.0", "eslint-plugin-import": "2.7.0", "eslint-watch": "3.1.2", - "express": "4.15.4", - "express-jwt": "5.3.0", + "express": "^4.17.1", + "express-jwt": "^5.3.1", "express-validation": "1.0.2", "express-winston": "2.4.0", "gulp": "3.9.1", "gulp-babel": "7.0.0", "gulp-load-plugins": "1.5.0", "gulp-newer": "1.3.0", - "gulp-nodemon": "2.2.1", + "gulp-nodemon": "^2.4.2", "gulp-sourcemaps": "2.6.1", "gulp-util": "3.0.8", - "helmet": "3.8.1", + "handlebars": "^4.7.3", + "helmet": "^3.21.1", + "http": "^0.0.1-security", + "http-proxy-middleware": "^1.0.6", "http-status": "1.0.1", + "https": "^1.0.0", + "https-proxy-agent": "^4.0.0", "istanbul": "1.0.0-alpha.2", "joi": "10.6.0", + "jsdom": "^16.2.0", "jsonwebtoken": "8.0.0", - "lodash": "4.17.4", + "jstoxml": "^1.6.7", + "lodash": "^4.17.15", "method-override": "2.3.9", + "migrate": "^1.6.2", "mocha": "3.5.0", - "moment": "2.18.1", + "moment": "^2.24.0", + "mongodb": "^3.1.13", "mongoose": "4.11.10", - "morgan": "1.8.2", + "mongoose-slug-generator": "^1.0.4", + "mongoose-unique-validator": "^2.0.2", + "morgan": "^1.9.1", "multer": "^1.3.0", + "page-metadata-parser": "^1.1.4", "passport": "0.4.0", "passport-facebook-token": "3.3.0", - "raccoon": "0.2.8", + "qs-mongodb": "^0.1.0", "randomstring": "^1.1.5", - "redis": "2.8.0", + "recaptcha2": "^1.3.2", + "request": "^2.88.2", "run-sequence": "2.1.0", "sendgrid": "^5.2.3", + "socket.io": "^2.3.0", "stripe": "^5.3.0", "supertest": "3.0.0", "supertest-as-promised": "4.0.2", "swagger-jsdoc": "^1.9.7", + "twitter-lite": "^0.13.0", + "url": "^0.10.3", "validate-commit-msg": "2.14.0", "winston": "2.3.1" }, diff --git a/server/controllers/answer.controller.js b/server/controllers/answer.controller.js new file mode 100644 index 00000000..f2f1e5b6 --- /dev/null +++ b/server/controllers/answer.controller.js @@ -0,0 +1,232 @@ +import isObject from 'lodash/isObject'; +import isString from 'lodash/isString'; +import Answer from '../models/answer.model'; +import Question from '../models/question.model'; +import Topic from '../models/topic.model'; +import { saveAndNotifyUser } from './notification.controller'; +import { mailTemplate } from '../helpers/mail'; +import { indexTopic } from './topicPage.controller'; + +async function list(req, res, next) { + req.posts = []; + + const isProduction = (process.env.NODE_ENV === 'production'); + const isMobile = ( + !req.headers.origin || + (isString(req.headers.origin) && req.headers.origin.indexOf('softwaredaily.com') < 0) + ); + + if (isProduction && isMobile) { + return next(); + } + + const options = { + $or: [ + { deleted: false }, + { deleted: { $exists: false } }, + ] + }; + + if (req.query.createdAfter) { + options.dateCreated = { $gt: req.query.createdAfter }; + } else if (req.query.createdAtBefore) { + options.dateCreated = { $lte: req.query.createdAtBefore }; + } + + try { + req.posts = await Answer + .find(options) + .populate([ + 'question', + 'author', + ]); + + req.posts = req.posts + .map((post) => { + const answer = post.toObject(); + + answer.type = 'answer'; + answer.date = answer.dateCreated; + + if (isObject(answer.question)) { + answer[`${answer.question.entityType}s`] = [answer.question.entityId]; + } + + return answer; + }); + } catch (err) { + return next(err); + } + + return next(); +} + +async function get(req, res) { + const answer = await Answer.findById(req.params.id); + + if (!answer) return res.status(404).send('Not found'); + + return res.json(answer.toObject()); +} + +async function create(req, res) { + const { question: questionId, content } = req.body; + + if (!questionId || !content) return res.status(400).send('Missing data'); + + const question = await Question + .findById(questionId) + .populate('author'); + + const topic = await Topic + .findOne({ _id: question.entityId }); + + if (!question) return res.status(404).send('Question not found'); + + if (!req.user) return res.status(401).send('Need to be logged'); + + const answer = new Answer({ + question: question._id, + content, + author: req.user._id + }); + + try { + const saved = await answer.save(); + + question.answers = question.answers.concat([saved._id]); + await question.save(); + + if (question && question.entityId) { + indexTopic(question.entityId); + } + + const canSend = !!( + question.author && + req.user && + question.author.email && + question.author.email !== req.user.email + ); + + const questionUrl = `/topic/${topic.slug}/question/${question._id}`; + const payload = { + notification: { + title: 'Someone answered your question', + body: saved.content, + data: { + user: req.user.username, + mentioned: question.author._id, + slug: topic.slug, + url: questionUrl, + } + }, + type: 'question', + entity: topic._id + }; + + if (canSend) { + // notify maintainer + saveAndNotifyUser(payload, question.author._id); + + // email maintainer + mailTemplate.topicAnswer({ + to: question.author.email, + subject: 'Someone answered your question', + data: { + user: question.author.name || '', + topic: topic.name, + actionLabel: 'View answer', + actionLink: `http://softwaredaily.com${questionUrl}`, + question: question.content || '', + } + }); + } + + return res.json(saved.toObject()); + } catch (e) { + return res.status(500).end(e.message ? e.message : e.toString()); + } +} + +async function update(req, res) { + if (!req.body.content) return res.status(400).send('Missing data'); + + const answer = await Answer + .findById(req.params.id) + .populate('question'); + + if (!answer) return res.status(404).send('Not found'); + + if (!req.user) return res.status(401).send('Need to be logged'); + + if (answer.author.toString() !== req.user._id.toString()) { + return res.status(401).send('You are not the author of this answer'); + } + + answer.content = req.body.content.trim(); + answer.dateUpdated = new Date(); + + try { + const saved = await answer.save(); + + if (answer.question && answer.question.entityId) { + indexTopic(answer.question.entityId); + } + + return res.json(saved.toObject()); + } catch (e) { + return res.status(500).end(e.message ? e.message : e.toString()); + } +} + +async function deleteAnswer(req, res) { + const answer = await Answer.findById(req.params.id); + + if (!answer) return res.status(404).send('Not found'); + + answer.deleted = true; + answer.dateUpdated = new Date(); + + try { + const saved = await answer.save(); + return res.json(saved.toObject()); + } catch (e) { + return res.status(500).end(e.message ? e.message : e.toString()); + } +} + +async function vote(req, res) { + const answer = await Answer.findById(req.params.id); + + if (!answer) return res.status(404).send('Not found'); + + if (!req.user) return res.status(401).send('Need to be logged'); + + if (answer.author.toString() === req.user._id.toString()) { + return res.status(401).send('Can\'t vote on own answer'); + } + + const ownVoted = answer.votes.find(v => v.toString() === req.user._id.toString()); + + if (ownVoted) { + answer.votes = answer.votes.filter(v => v.toString() !== req.user._id.toString()); + } else { + answer.votes = answer.votes.concat([req.user._id]); + } + + try { + const saved = await answer.save(); + return res.json(saved.toObject()); + } catch (e) { + return res.status(500).end(e.message ? e.message : e.toString()); + } +} + +export default { + list, + get, + create, + update, + delete: deleteAnswer, + vote +}; diff --git a/server/controllers/auth.controller.js b/server/controllers/auth.controller.js index a1c40264..bab54cce 100644 --- a/server/controllers/auth.controller.js +++ b/server/controllers/auth.controller.js @@ -1,17 +1,33 @@ import _ from 'lodash'; -import FacebookTokenStrategy from 'passport-facebook-token'; import passport from 'passport'; import jwt from 'jsonwebtoken'; import httpStatus from 'http-status'; +import ReCAPTCHA from 'recaptcha2'; +import Twitter from 'twitter-lite'; import APIError from '../helpers/APIError'; import config from '../../config/config'; import User from '../models/user.model'; +import Passport from '../models/passport.model'; import { signS3 } from '../helpers/s3'; -import { sendError, ErrorType } from '../helpers/events.helper'; const http = require('http'); // For mailchimp api call require('dotenv').config(); +const reCaptcha = new ReCAPTCHA({ + siteKey: config.recaptcha.siteKey, + secretKey: config.recaptcha.secretKey +}); + +const twitterOptions = { + access_token_key: process.env.OAUTH_TWITTER_ACCESS_TOKEN_KEY, + access_token_secret: process.env.OAUTH_TWITTER_ACCESS_TOKEN_SECRET, + consumer_key: process.env.OAUTH_TWITTER_CONSUMER_KEY, + consumer_secret: process.env.OAUTH_TWITTER_CONSUMER_SECRET, +}; + +const client = new Twitter(twitterOptions); +const REGEX_CASE_INSENSITIVE_MOD = 'i'; + /** * @swagger * tags: @@ -29,38 +45,6 @@ passport.deserializeUser((id, done) => { }); }); -// TODO: add swagger doc - -passport.use(new FacebookTokenStrategy( - { - clientID: config.facebook.clientID, - clientSecret: config.facebook.clientSecret - }, - (accessToken, refreshToken, profile, done) => { - const username = profile.emails[0].value || profile.id; - User.findOne({ username }) - .exec() - .then((user) => { - if (!user) { - const newUser = new User(); - newUser.username = username; - newUser.facebook = { - email: profile.emails[0].value, - name: `${profile.name.givenName} ${profile.name.familyName}`, - id: profile.id, - token: accessToken - }; - return newUser.save().then(userSaved => done(null, userSaved)); - } - return done(null, user); - }) - .catch((err) => { - err = new APIError('Authentication error', httpStatus.UNAUTHORIZED, true); //eslint-disable-line - return done(err); - }); - } -)); - /** * @swagger * /auth/login: @@ -91,9 +75,11 @@ passport.use(new FacebookTokenStrategy( function login(req, res, next) { const { username } = req.body; const { password } = req.body; - User.findOne({ - $or: [{ username }, { email: username }] + $or: [ + { username: new RegExp(username, REGEX_CASE_INSENSITIVE_MOD) }, + { email: new RegExp(username, REGEX_CASE_INSENSITIVE_MOD) } + ] }) .exec() .then((user) => { @@ -119,7 +105,7 @@ function loginWithEmail(req, res, next) { const { email } = req.body; const { password } = req.body; - User.findOne({ email }) + User.findOne({ email: new RegExp(email, REGEX_CASE_INSENSITIVE_MOD) }) .exec() .then((user) => { if (!user) return res.status(404).json({ message: 'User not found.' }); @@ -140,6 +126,120 @@ function loginWithEmail(req, res, next) { }); } +function twitterRequest(req, res) { + client + .getRequestToken(req.body.callback) + .then((reply) => { + return res.status(200).json(reply); + }) + .catch((err) => { + return res.status(404).json({ message: err.message || err.toString() }); + }); +} + +async function twitterAccess(req, res) { + try { + let user = null; + let newPassport = null; + + const jwtOptions = { expiresIn: '40000h' }; + const { oauth_token, oauth_token_secret } = await client + .getAccessToken({ + oauth_token: req.body.oauth_token, + oauth_verifier: req.body.oauth_verifier, + }); + + const clientUser = new Twitter({ + ...twitterOptions, + access_token_key: oauth_token, + access_token_secret: oauth_token_secret, + }); + + const twitterUser = await clientUser.get('account/verify_credentials', { + include_email: true, + }); + + const existingPassport = await Passport + .findOne({ + provider: 'twitter', + identifier: twitterUser.screen_name, + accessToken: oauth_token, + user: { $exists: true }, + }) + .exec(); + + if (!twitterUser) { + return res.status(404).json({ message: 'Error logging you in' }); + } + + if (existingPassport && existingPassport.user) { + user = await User + .findOne({ _id: existingPassport.user }) + .exec(); + } else { + // No passport, let's find user via email + user = await User + .findOne({ email: twitterUser.email }) + .exec(); + + newPassport = new Passport({ + identifier: twitterUser.screen_name, + accessToken: oauth_token, + tokens: { + oauth_token, + oauth_token_secret, + } + }); + + if (user) { + newPassport.user = user._id; + await newPassport.save(); + } + } + + if (user) { + return res.status(201).json({ + user, + token: jwt.sign(user.toJSON(), config.jwtSecret, jwtOptions), + }); + } + + // No user, let's create one + const newUser = new User(); + const newValues = { + name: twitterUser.name, + username: twitterUser.screen_name, + twitter: twitterUser.screen_name, + avatarUrl: twitterUser.profile_image_url_https, + bio: twitterUser.description, + about: twitterUser.description, + website: twitterUser.url, + email: twitterUser.email, + password: User.generateHash(oauth_token_secret), + }; + + Object.assign(newUser, newValues); + + user = await newUser.save(); + + newPassport.user = user._id; + newPassport.save(); + + return res.status(201).json({ + user, + token: jwt.sign(user.toJSON(), config.jwtSecret, jwtOptions), + }); + } catch (err) { + if (err && _.isArray(err.errors)) { + return res.status(401).json(err.errors); + } + + return res.status(401).json({ + message: err.message || err.toString() + }); + } +} + /** * @swagger * /auth/register: @@ -173,27 +273,31 @@ function loginWithEmail(req, res, next) { */ function register(req, res, next) { - const { username } = req.body; const { password } = req.body; const newsletterSignup = req.body.newsletter; - if (!username) { - let err = new APIError('Username is required to register.', httpStatus.UNAUTHORIZED, true); //eslint-disable-line - return next(err); - } + // a simple, non conflict, random id. Ex: K7DRS1HR + const username = (Date.now() + Math.floor(Math.random() * Math.floor(99999))) + .toString(36) + .toUpperCase(); if (!password) { - let err = new APIError('Password is required to register.', httpStatus.UNAUTHORIZED, true); //eslint-disable-line + let err = new APIError('Password is required to register.', httpStatus.UNAUTHORIZED, true); // eslint-disable-line return next(err); } - const { email } = req.body; const queryIfEmail = { - $or: [{ username }, { email }] + $or: [ + { username: new RegExp(username, REGEX_CASE_INSENSITIVE_MOD) }, + { email: new RegExp(email, REGEX_CASE_INSENSITIVE_MOD) } + ] }; const queryIfEmailMissing = { - $or: [{ username }, { email: username }] + $or: [ + { username: new RegExp(username, REGEX_CASE_INSENSITIVE_MOD) }, + { email: username } + ] }; // We do this so people can't share an email on either field, username or email: @@ -221,36 +325,22 @@ function register(req, res, next) { const mailchimpReq = http.request(options, (mailchimpRes) => { mailchimpRes.setEncoding('utf8'); mailchimpRes.on('data', (body) => { - console.log(`Body: ${body}`); + console.log(`Body: ${body}`); // eslint-disable-line }); }); mailchimpReq.on('error', (e) => { - console.log(`mailchimp error: ${e}`); - sendError({ - userName: username, - errorType: ErrorType.OTHER, - errorData: { - message: e - } - }); + console.log(`mailchimp error: ${e}`); // eslint-disable-line const error = new APIError('Mailchimp error', httpStatus.UNAUTHORIZED, true); - console.log('newsletter error', error); + console.log('newsletter error', error); // eslint-disable-line // return next(error); // This will prevent registration which we dont want }); mailchimpReq.write(postData); mailchimpReq.end(); } } catch (e) { - console.log(`mailchimp error: ${e}`); - sendError({ - userName: username, - errorType: ErrorType.OTHER, - errorData: { - message: e - } - }); + console.log(`mailchimp error: ${e}`); // eslint-disable-line const error = new APIError('Mailchimp error', httpStatus.UNAUTHORIZED, true); - console.log('newsletter error2', error); + console.log('newsletter error2', error); // eslint-disable-line // return next(error); // This will prevent registration which we dont want } @@ -266,7 +356,7 @@ function register(req, res, next) { newUser.password = User.generateHash(password); newUser.signedupForNewsletter = newsletterSignup; // Probably works // We assign a set of "approved fields" - const newValues = _.pick(req.body, User.updatableFields); + const newValues = { username, ..._.pick(req.body, User.updatableFields) }; Object.assign(newUser, newValues); return newUser.save(); @@ -313,7 +403,7 @@ function signS3AvatarUpload(req, res, next) { return next(error); } }; - signS3('sd-profile-pictures', fileType, newFileName, cbSuccess, cbError); + signS3(config.aws.profilePicBucketName, fileType, newFileName, cbSuccess, cbError); } /** @@ -341,12 +431,27 @@ function getRandomNumber(req, res) { }); } +function validateRecaptcha(req, res) { + const { recaptchaResponse } = req.body; + reCaptcha.validate(recaptchaResponse) + .then(() => res.status(200).json({ + formSubmit: true + })) + .catch(errorCodes => res.status(401).json({ + formSubmit: false, + errors: reCaptcha.translateErrors(errorCodes) + })); +} + export default { login, loginWithEmail, + twitterRequest, + twitterAccess, getRandomNumber, register, socialAuth, signS3, - signS3AvatarUpload + signS3AvatarUpload, + validateRecaptcha }; diff --git a/server/controllers/bookmark.controller.js b/server/controllers/bookmark.controller.js index 0d439520..db9da0b2 100644 --- a/server/controllers/bookmark.controller.js +++ b/server/controllers/bookmark.controller.js @@ -165,32 +165,47 @@ function list(req, res, next) { */ function bookmark(req, res, next) { const { post } = req; - if (!post.totalFavorites) post.totalFavorites = 0; + const newFavorite = new Favorite(); - Favorite.findOne({ - postId: post._id, - userId: req.user._id - }) + if (!post.totalFavorites) { + post.totalFavorites = 0; + } + + Favorite + .findOne({ + postId: post._id, + userId: req.user._id + }) .then((favoriteFound) => { const favorite = favoriteFound; if (favorite) { post.totalFavorites = !favorite.active ? post.totalFavorites + 1 : post.totalFavorites - 1; + post.totalFavorites = Math.max(post.totalFavorites, 0); favorite.active = !favorite.active; - return Bluebird.all([favorite.save(), post.save()]); + return Bluebird.all([ + favorite.save(), + post.save(), + ]); } - const newFavorite = new Favorite(); newFavorite.postId = post._id; newFavorite.userId = req.user._id; post.totalFavorites += 1; - return Bluebird.all([newFavorite.save(), post.save()]); + return Bluebird.all([ + newFavorite.save(), + post.save(), + ]); }) - .then((favorite) => { - req.favorite = favorite[0]; // eslint-disable-line - return res.json(favorite[0]); + .then(([favorite, _post]) => { + req.favorite = favorite; // eslint-disable-line + + return res.json({ + ...favorite.toObject(), + totalFavorites: _post.totalFavorites || 0, + }); }) .catch((e) => { next(e); @@ -241,34 +256,52 @@ function bookmark(req, res, next) { */ function unbookmark(req, res, next) { const { post } = req; - if (!post.totalFavorites) post.totalFavorites = 0; + const newFavorite = new Favorite(); - Favorite.findOne({ - postId: post._id, - userId: req.user._id - }) + if (!post.totalFavorites) { + post.totalFavorites = 0; + } + + Favorite + .findOne({ + postId: post._id, + userId: req.user._id + }) .then((favoriteFound) => { const favorite = favoriteFound; if (favorite) { if (favorite.active) { post.totalFavorites -= 1; + post.totalFavorites = Math.max(post.totalFavorites, 0); favorite.active = false; } - return Bluebird.all([favorite.save(), post.save()]); + return Bluebird.all([ + favorite.save(), + post.save(), + ]); } - const newFavorite = new Favorite(); newFavorite.active = false; newFavorite.postId = post._id; newFavorite.userId = req.user._id; - return Bluebird.all([newFavorite.save()]); + post.totalFavorites -= 1; + post.totalFavorites = Math.max(post.totalFavorites, 0); + + return Bluebird.all([ + newFavorite.save(), + post.save(), + ]); }) - .then((favorite) => { + .then(([favorite, _post]) => { req.favorite = favorite; // eslint-disable-line - return res.json(favorite[0]); + + return res.json({ + ...favorite.toObject(), + totalFavorites: _post.totalFavorites || 0, + }); }) .catch((e) => { next(e); diff --git a/server/controllers/comment.controller.js b/server/controllers/comment.controller.js index f7a54f56..0776f303 100644 --- a/server/controllers/comment.controller.js +++ b/server/controllers/comment.controller.js @@ -6,7 +6,10 @@ import moment from 'moment'; import Comment from '../models/comment.model'; import User from '../models/user.model'; import ForumThread from '../models/forumThread.model'; -import ForumNotifications from '../helpers/forumNotifications.helper'; +import MailNotification from '../helpers/mailNotification.helper'; +import { subscribePostFromEntity, notifyPostSubscribersFromEntity } from '../controllers/postSubscription.controller'; +import { subscribeTopicPage, notifySubscribers } from '../controllers/topicPageSubscription.controller'; +import { saveAndNotifyUser } from '../controllers/notification.controller'; /* * Load comment and append to req. */ @@ -51,6 +54,7 @@ function load(req, res, next, id) { */ function remove(req, res, next) { const { comment, user } = req; + if (comment && user) { if (comment.author._id.toString() !== user._id.toString()) { return res.status(401).json({ Error: 'Please login' }); @@ -64,10 +68,14 @@ function remove(req, res, next) { // Sucess: res.json({ deleted: true }); }) + .then(() => { + ForumThread.increaseCommentCount(comment.rootEntity, -1); + }) .catch((e) => { next(e); }); } + return res.status(500).json({}); } @@ -82,7 +90,7 @@ async function idsToUsers(ids) { const user = await User.get(id); users.push(user); } catch (e) { - console.log('e.idsToUsers', e); + console.log('e.idsToUsers', e); // eslint-disable-line } } /* eslint-disable no-await-in-loop */ @@ -105,32 +113,34 @@ function extractedNewMentions(comment, updatedMentions) { async function update(req, res, next) { const { comment, user } = req; - const { content, mentions } = req.body; + const { content, mentions, highlight } = req.body; + if (comment && user) { if (comment.author._id.toString() !== user._id.toString()) { return res.status(401).json({ Error: 'Please login' }); } + if (highlight) { + comment.highlight = highlight; + } + + comment.content = content; + comment.dateLastEdited = Date(); + if (mentions) { try { const updatedMentions = await idsToUsers(mentions); - const usersWeShouldEmail = extractedNewMentions(comment, updatedMentions); + const newMentions = extractedNewMentions(comment, updatedMentions); comment.mentions = updatedMentions; - ForumNotifications.sendMentionsNotificationEmail({ - content, - threadId: comment.rootEntity, - userWhoReplied: user, - usersMentioned: usersWeShouldEmail - }); + const { rootEntity: entityId, entityType } = comment; + MailNotification.handleUpdatedComment(entityId, entityType, user, comment, newMentions); } catch (e) { - console.log('e', e); + console.log('e', e); // eslint-disable-line } } else { comment.mentions = []; } - comment.content = content; - comment.dateLastEdited = Date(); return comment .save() .then((editedComment) => { @@ -181,66 +191,132 @@ async function update(req, res, next) { * $ref: '#/responses/NotFound' */ +async function subscribeAndNotifyCommenter(entityId, entityType, user, ignoreNotify) { + const payload = { + notification: { + title: `New comment from @${user.name}`, + }, + type: 'comment', + }; + + if (entityType.toLowerCase() === 'forumthread') { + const post = await subscribePostFromEntity(entityId, user); + payload.notification.body = post.title.rendered; + payload.notification.data = { + user: user.username, + slug: post.slug, + url: `/post/${post._id}/${post.slug}`, + thread: post.thread + }; + payload.entity = post._id; + // notify all subscribers + await notifyPostSubscribersFromEntity(entityId, user, payload, ignoreNotify); + } + + if (entityType.toLowerCase() === 'topic') { + const topic = await subscribeTopicPage(entityId, user); + payload.notification.body = topic.name; + payload.notification.data = { + user: user.username, + slug: topic.slug, + url: `/topic/${topic.slug}` + }; + payload.entity = entityId; + // notify all subscribers + await notifySubscribers(entityId, user, payload, ignoreNotify); + } +} + +async function subscribeAndNotifyMentioned(entityId, entityType, mentioned, user) { + if (entityType.toLowerCase() === 'forumthread') { + const post = await subscribePostFromEntity(entityId, mentioned); + + const payload = { + notification: { + title: `You were mentioned by @${user.name}`, + body: post.title.rendered, + data: { + user: user.username, + mentioned: mentioned._id, + slug: post.slug, + url: `/post/${post._id}/${post.slug}`, + thread: post.thread + } + }, + type: 'mention', + entity: post._id + }; + + // just notify the mentioned user + saveAndNotifyUser(payload, mentioned._id); + } + if (entityType.toLowerCase() === 'topic') { + const topic = await subscribeTopicPage(entityId, mentioned); + const payload = { + notification: { + title: `You were mentioned by @${user.name}`, + body: topic.name, + data: { + user: user.username, + mentioned: mentioned._id, + url: `/topic/${topic.slug}`, + slug: topic.slug + } + }, + type: 'mention', + entity: entityId + }; + + // just notify the mentioned user + saveAndNotifyUser(payload, mentioned._id); + } +} + async function create(req, res, next) { const { entityId } = req.params; const { parentCommentId, mentions } = req.body; - const { content, entityType } = req.body; + const { content, entityType, highlight } = req.body; const { user } = req; const comment = new Comment(); - comment.content = content; + comment.content = content || ''; + + if (!highlight && !content) { + return res.status(500).json({ Error: 'Property `content` is required when not a highlight' }); + } + let usersMentioned = []; if (mentions) { usersMentioned = await idsToUsers(mentions); comment.mentions = usersMentioned; + usersMentioned.forEach((mentioned) => { + subscribeAndNotifyMentioned(entityId, entityType, mentioned, user); + }); + } + + if (highlight) { + comment.highlight = highlight; } comment.rootEntity = entityId; + comment.entityType = entityType; // If this is a child comment we need to assign it's parent if (parentCommentId) { comment.parentComment = parentCommentId; } comment.author = user._id; - comment + return comment .save() - .then((commentSaved) => { - // TODO: result key is not consistent with other responses, consider changing this - if (entityType) { - switch (entityType.toLowerCase()) { - case 'forumthread': - - // TODO: move these so we also email for posts: - // get entity outside of this function and then pass down: - if (parentCommentId) { - // TODO: don't email if you are the author and replying to own stuff: - ForumNotifications.sendReplyNotificationEmail({ - content, - threadId: entityId, - userWhoReplied: user - }); - } - - if (mentions) { - ForumNotifications.sendMentionsNotificationEmail({ - parentCommentId, - content, - threadId: entityId, - userWhoReplied: user, - usersMentioned - }); - } - - ForumNotifications.sendForumNotificationEmail({ - threadId: entityId, - content, - userWhoReplied: user - }); - return ForumThread.increaseCommentCount(entityId).then(() => - res.status(201).json({ result: commentSaved })); - default: - } + .then(async (commentSaved) => { + subscribeAndNotifyCommenter(entityId, entityType, user, mentions); // don't await + + MailNotification.handleNotification(entityId, entityType, user, comment); + + if (entityType && entityType.toLowerCase() === 'forumthread') { + ForumThread.increaseCommentCount(entityId); } + return res.status(201).json({ result: commentSaved }); }) .catch(err => next(err)); diff --git a/server/controllers/company.controller.js b/server/controllers/company.controller.js index 1e34270c..ed6cc79d 100644 --- a/server/controllers/company.controller.js +++ b/server/controllers/company.controller.js @@ -2,6 +2,7 @@ import httpStatus from 'http-status'; import Company from '../models/company.model'; import APIError from '../helpers/APIError'; import { signS3 } from '../helpers/s3'; +import config from '../../config/config'; export default { list: async (req, res, next) => { @@ -60,7 +61,7 @@ export default { return next(error); } }; - signS3('sd-profile-pictures', fileType, newFileName, cbSuccess, cbError); + signS3(config.aws.profilePicBucketName, fileType, newFileName, cbSuccess, cbError); }, update: async (req, res, next) => { try { diff --git a/server/controllers/cron.controller.js b/server/controllers/cron.controller.js new file mode 100644 index 00000000..fba50ad7 --- /dev/null +++ b/server/controllers/cron.controller.js @@ -0,0 +1,34 @@ +import rssPublic from '../crons/rssFeed.cron'; + +const cronItems = [rssPublic]; + +class CronJobs { + constructor() { + this.jobs = []; + this.initialStart = true; + this.createJobs(); + } + + createJobs() { + cronItems.forEach((item) => { + item.createJob(); + this.jobs.push(item); + }); + } + + start() { + this.jobs.forEach((item) => { + item.job.start(); + if (item.runOnInit && this.initialStart) item.callback(); + }); + this.initialStart = false; // run just on app start + } + + pause() { + console.log('Pausing CronJobs'); + this.jobs.forEach((item) => { + item.job.stop(); + }); + } +} +export default CronJobs; diff --git a/server/controllers/job.controller.js b/server/controllers/job.controller.js index 62118517..c73c26ba 100644 --- a/server/controllers/job.controller.js +++ b/server/controllers/job.controller.js @@ -2,9 +2,9 @@ import httpStatus from 'http-status'; import { map } from 'lodash'; import Job from '../models/job.model'; import APIError from '../helpers/APIError'; -import sgMail from '../helpers/mail'; +import { sgMail } from '../helpers/mail'; import transform from '../helpers/job.helper'; -import { sendError, ErrorType } from '../helpers/events.helper'; +import config from '../../config/config'; require('babel-polyfill'); @@ -42,7 +42,7 @@ export default { query.where({ tags: { $in: tagsAsNumbers } }); } - const jobs = await query.sort('-postedDate').exec(); + const jobs = await query.sort('-postedDate').populate('topics').exec(); const transformedJobs = map(jobs, job => transform(job, false)); return res.json(transformedJobs); @@ -134,7 +134,8 @@ export default { get: async (req, res, next) => { try { const job = await Job - .findById(req.params.jobId); + .findById(req.params.jobId) + .populate('topics'); if (!job) { return next(new APIError('Job not found', httpStatus.NOT_FOUND)); @@ -202,6 +203,7 @@ export default { if (job.postedUser.toString() === req.user._id.toString()) { return next(new APIError('Unable to apply for a job you posted', httpStatus.FORBIDDEN)); } + const today = new Date().getDate(); if (job.isDeleted || (job.expirationDate && job.expirationDate < today)) { @@ -218,7 +220,7 @@ export default { const msg = { to: job.applicationEmailAddress, - from: 'no-reply@softwaredaily.com', + from: config.email.fromAddress, subject: `Job Application : ${job.title}`, text: req.body.coveringLetter, attachments: [ @@ -232,16 +234,9 @@ export default { }; await sgMail.send(msg); + return res.sendStatus(httpStatus.OK); } catch (err) { - sendError({ - userName: req.user._id, - errorType: ErrorType.OTHER, - errorData: { - message: err.message - } - }); - return next(err); } } diff --git a/server/controllers/like.controller.js b/server/controllers/like.controller.js new file mode 100644 index 00000000..1dbc6774 --- /dev/null +++ b/server/controllers/like.controller.js @@ -0,0 +1,94 @@ +import algoliasearch from 'algoliasearch'; +import Vote from '../models/vote.model'; +import Post from '../models/post.model'; + +function syncAlgolia(query) { + if (process.env.NODE_ENV === 'test') { + return; + } + + const client = algoliasearch( + process.env.ALGOLIA_APP_ID, + process.env.ALGOLIA_API_KEY, + ); + + const index = client.initIndex(process.env.ALGOLIA_POSTS_INDEX); + + index.partialUpdateObject(query); +} + +/** + * @swagger + * tags: + * - name: like + * description: Manages liking of posts + */ + +/** + * @swagger + * /posts/{postId}/like: + * active: + * summary: Uplike episode by ID + * description: Uplike episode by ID + * tags: [like] + * security: + * # indicates security authorization required + * # empty array because no "scopes" for non-OAuth + * - Token: [] + * parameters: + * - $ref: '#/parameters/postId' + * responses: + * '200': + * description: successful operation + * schema: + * $ref: '#/definitions/Like' + * '401': + * $ref: '#/responses/Unauthorized' + * '404': + * $ref: '#/responses/NotFound' + */ +async function likePost(req, res) { + const { postId } = req.params; + const { _id: userId } = req.user; + const query = { + postId, + userId, + direction: 'upvote', + active: true, + }; + + const like = new Vote(query); + const likeActive = await Vote.findOne(query); + const score = likeActive ? -1 : 1; + + if (likeActive) { + await Vote.deleteOne({ _id: likeActive._id }); + } else { + await like.save(); + } + + Post + .findOneAndUpdate( + { _id: postId }, + { $inc: { score } }, + { new: true }, + ).exec(async (err, reply) => { + if (err) { + return res.status(500).json({ message: 'Error liking post' }); + } + + syncAlgolia({ + score: reply.score, + objectID: reply.id, + }); + + return res.json({ + score: reply.score, + upvoted: !(likeActive), + }); + }); +} + +export default { + likePost, +}; diff --git a/server/controllers/mailTemplate.controller.js b/server/controllers/mailTemplate.controller.js new file mode 100644 index 00000000..b28f46ec --- /dev/null +++ b/server/controllers/mailTemplate.controller.js @@ -0,0 +1,97 @@ +import handlebars from 'handlebars'; +import fs from 'fs'; +import path from 'path'; +import { series } from 'async'; +import config from '../../config/config'; + +const templateFolder = path.resolve('server/templates/email'); + +function getFiles(files, folder, callback) { + const result = []; + const items = []; + for (const idx in files) { // eslint-disable-line + items.push((cb) => { + fs.readFile(`${templateFolder}/${files[idx]}.handlebars`, (err, res) => { + if (err) return cb(err); + result.push({ + name: files[idx], + data: res.toString() + }); + return cb(); + }); + }); + } + series(items, (err) => { + if (err) return console.error(`[MailTemplate] ${err}`); + return callback(result); + }); +} + +class MailTemplate { + constructor(options, sgMail) { + this.sgMail = sgMail; + this.options = options; + this.prepareBlankTemplates(); + this.registerPartials(); + } + + prepareBlankTemplates() { + this.options.mailTemplates.forEach((template) => { + this[template.name] = () => {}; + }); + } + + registerPartials() { + getFiles(this.options.templatesFiles, templateFolder, (files) => { + files.forEach((template) => { + handlebars.registerPartial(template.name, template.data); + }); + this.compileTemplates(); + }); + } + + compileTemplates() { + this.compiledTemplates = {}; + getFiles(this.options.bodiesFiles, templateFolder, (files) => { + files.forEach((template) => { + this.compiledTemplates[template.name] = handlebars.compile(template.data); + }); + this.prepateTemplates(); + }); + } + + prepateTemplates() { + this.options.mailTemplates.forEach((mailTemplate) => { + this[mailTemplate.name] = (options) => { + if (!this.compiledTemplates[mailTemplate.body]) { + const msg = `[MailTemplate] handlebars template ${mailTemplate.template} not found`; + console.error(msg); + return false; + } + return this.sendMail(options, this.compiledTemplates[mailTemplate.body]); + }; + }); + } + + sendMail(options, template) { + const content = (options.data) ? template.apply(this, [options.data]) : ''; + + const mailMsg = { + from: options.from || config.email.fromAddress, + html: content, + text: options.text || content.replace(/(<([^>]+)>)/ig, ''), + ...options + }; + + return (async () => { + try { + this.sgMail.send(mailMsg); + return true; + } catch (e) { + console.error(`[SendGrid] ${e}`); + return false; + } + })(); + } +} +export default MailTemplate; diff --git a/server/controllers/notification.controller.js b/server/controllers/notification.controller.js new file mode 100644 index 00000000..ba846615 --- /dev/null +++ b/server/controllers/notification.controller.js @@ -0,0 +1,82 @@ +import { queue } from 'async'; +import Notification from '../models/notification.model'; +import websocket from '../../config/websocket'; + +// queue for low priority +const notificationSaveQueue = queue(saveNotification, 1); +const notificationQueue = queue(execSendNotification, 1); + +async function saveNotification(task, next) { + const { user, payload } = task; + + const notification = new Notification({ + to: user, + notification: payload.notification, + type: payload.type, + entity: payload.entity + }); + + try { + await notification.save(); + } catch (e) { + console.error(e); + return next(); + } + + sendNotifications(user); + return next(); +} + +function sendNotifications(user) { + notificationQueue.push(user); +} + +async function execSendNotification(user, next) { + try { + if (!user) return next(); + + const userId = user.toString(); + + const connected = websocket.isConnected(userId); + if (!connected) return next(); + + // find all notifications that we need to send + const notifications = await Notification.find({ to: user }) + .sort('-dateCreated') + .limit(20) + .lean() + .exec(); + + notifications.forEach((n) => { + if (['comment', 'upvote', 'mention'].includes(n.type) && !n.notification.data.url) { + n.notification.data.url = `/post/${n.entity}/${n.notification.data.slug}`; // eslint-disable-line no-param-reassign + } + }); + + websocket.to(userId).emit('refresh.full', notifications); + + return next(); + } catch (e) { + console.error(e); + return next(); + } +} + +function saveAndNotifyUser(payload, user) { + notificationSaveQueue.push({ payload, user }); +} + +async function markReadAll(userId) { + try { + const result = await Notification.updateMany({ to: userId }, { $set: { read: true } }); + if (result && result.nModified) sendNotifications(userId); + } catch (e) { + console.error(e); + } +} + +export default { + saveAndNotifyUser, + sendNotifications, + markReadAll +}; diff --git a/server/controllers/post.controller.js b/server/controllers/post.controller.js index 51ab07d8..5237cb0d 100644 --- a/server/controllers/post.controller.js +++ b/server/controllers/post.controller.js @@ -1,11 +1,30 @@ -// import mongoose from 'mongoose'; - +import uniq from 'lodash/uniq'; +import find from 'lodash/find'; +import flatten from 'lodash/flatten'; +import moment from 'moment'; +import algoliasearch from 'algoliasearch'; import Post from '../models/post.model'; +import Topic from '../models/topic.model'; import { - getAdFreeSinglePostIfSubscribed, - getAdFreePostsIfSubscribed + addPostData, + getAdFreePostsIfSubscribed, } from '../helpers/post.helper'; +async function populateTopics(posts) { + const _topics = uniq(flatten(posts.map(p => p.topics.map(id => id.toString())))); + const topics = await Topic.find({ _id: { $in: _topics } }); + + return posts.map((post) => { + post.topics = post.topics // eslint-disable-line no-param-reassign + .map((topicId) => { + return find(topics, { id: topicId.toString() }); + }) + .filter(t => !!(t)); + + return post; + }); +} + /** * @swagger * tags: @@ -52,9 +71,46 @@ function load(req, res, next, id) { * $ref: '#/responses/NotFound' */ -function get(req, res, next) { - // Load ad free version of podcast episode if subscrbied: - return res.json(getAdFreeSinglePostIfSubscribed(req.post.toObject(), req.fullUser, next)); +async function get(req, res, next) { + req.response = await addPostData( + req.post.toObject(), + req.fullUser, + next + ); + + req.topicIds = req.response.topics || []; + + return next(); +} + +/** + * @swagger + * /posts/popular: + * get: + * summary: Get posts by score + * description: Get posts by score + * responses: + * '200': + * description: successful operation + * schema: + * $ref: '#/definitions/Post' + * '404': + * $ref: '#/responses/NotFound' + */ + +async function popular(req, res) { + const oneMonthAgo = moment().subtract(1, 'month').toDate(); + + try { + const posts = await Post + .find({ date: { $gte: oneMonthAgo } }) + .limit(parseInt(req.query.limit || 5, 10)) + .sort('-score'); + + return res.json({ posts }); + } catch (err) { + return res.status(404).json({ message: err.message || err.toString() }); + } } /** @@ -82,6 +138,13 @@ function get(req, res, next) { * required: false * description: The date/time the episode was created after * - in: query + * name: transcripts + * type: boolean + * required: false + * description: | + * Using true returns posts with a transcriptUrl field, + * using false returns posts without + * - in: query * name: type * type: string * required: false @@ -117,16 +180,20 @@ function list(req, res, next) { type = null, tags = null, categories = null, - search = null + search: _search = null, + transcripts = null, + topic = null } = req.query; const query = {}; + if (limit) query.limit = limit; if (createdAtBefore) query.createdAtBefore = createdAtBefore; if (createdAfter) query.createdAfter = createdAfter; if (type) query.type = type; if (req.user) query.user = req.user; - if (search) query.search = search; + if (_search) query.search = _search; + if (transcripts) query.transcripts = transcripts; if (tags) { query.tags = tags.split(','); @@ -146,8 +213,20 @@ function list(req, res, next) { query.categories = newTags; } + if (topic) { + query.topic = [topic]; + } + Post.list(query) - .then(posts => res.json(getAdFreePostsIfSubscribed(posts, req.fullUser, next))) + .then(async (posts) => { + const response = await getAdFreePostsIfSubscribed(posts, req.fullUser, next); + + req.posts = req.posts.concat(response); + req.posts.sort((a, b) => b.date - a.date); + req.posts = await populateTopics(req.posts || []); + + return res.json(req.posts); + }) .catch(e => next(e)); } @@ -176,56 +255,207 @@ function list(req, res, next) { */ function recommendations(req, res) { - // const numberOfRecommendations = 10; + // Raccoon recommendations were removed, so we return empty list for now res.json([]); - /* - raccoon - .recommendFor(req.user._id.toString(), numberOfRecommendations) - .then((recommendationsFound) => { - const ids = recommendationsFound.map(rec => - //eslint-disable-line - mongoose.Types.ObjectId(rec) //eslint-disable-line - ); //eslint-disable-line - return Post.find({ _id: { $in: ids } }).populate('thread').lean(); +} + +/** + * @swagger + * /posts: + * get: + * summary: Make algolia search request + * description: Get posts based on algolia search query + * tags: [post] + * security: [] #indicates no authorization required to use route + * parameters: + * - $ref: '#/parameters/limit' + * - in: query + * name: query + * type: string + * format: date-time #All date-time format follow https://xml2rfc.tools.ietf.org/public/rfc/html/rfc3339.html#anchor14 + * required: false + * description: search term + * - in: query + * name: page + * type: integer + * format: int64 + * required: true + * description: search page number + * responses: + * '200': + * description: successful operation + * schema: + * type: array + * items: + * $ref: '#/definitions/Post' + */ + +function search(req, res, next) { + let isEnd = false; + let nextPage = 0; + let slugs = []; + + const { query = '' } = req.query; + const page = parseInt(req.query.page || '0', 10); + + const client = algoliasearch( + process.env.ALGOLIA_APP_ID, + process.env.ALGOLIA_API_KEY, + ); + + const index = client.initIndex(process.env.ALGOLIA_POSTS_INDEX); + const searchQuery = { + query, + page, + hitsPerPage: 10, + }; + + index.search(searchQuery) + .then((reply) => { + nextPage = (page >= reply.nbPages) ? reply.nbPages : page + 1; + isEnd = (nextPage === reply.nbPages); + slugs = reply.hits.map(h => h.slug); + + Post.find({ slug: { $in: slugs } }) + .then(async (posts) => { + posts = await getAdFreePostsIfSubscribed(posts, req.fullUser, next); // eslint-disable-line + posts = await populateTopics(posts || []); // eslint-disable-line no-param-reassign + + res.json({ posts, isEnd, nextPage }); + }) + .catch(e => next(e)); }) - .then(posts => - //eslint-disable-line - res.json(getAdFreePostsIfSubscribed(posts, req.fullUser, next))) - .catch((e) => { - next(e); - }); - */ + .catch(e => next(e)); } function upvote(req, res, next) { - /* - const userIdString = req.user._id.toString(); - const postIdString = req.post._id.toString(); - if (req.liked) { - // raccoon.liked(userIdString, postIdString); - } else if (req.unliked) { - // raccoon.unliked(userIdString, postIdString); - } - */ + // Raccoon recommendations were removed, vote logic moved to vote controller next(); } function downvote(req, res, next) { - /* - if (req.undisliked) { - // raccoon.undisliked(req.user._id.toString(), req.post._id.toString()); - } else if (req.disliked) { - // raccoon.disliked(req.user._id.toString(), req.post._id.toString()); - } - */ + // Raccoon recommendations were removed, vote logic moved to vote controller next(); } +async function getRelatedEpisodes(req, res) { + let post = await Post.findById(req.params.postId) + .populate('relatedPosts', 'slug title score'); + + if (!post) return res.json([]); + + post = post.toObject(); + + const topics = uniq(post.topics); + let _relatedPosts = []; + const relatedPosts = []; + + /* eslint-disable no-await-in-loop */ + for (let i = 0; i < topics.length; i += 1) { + const posts = await Post.find({ topics: { $in: [topics[i]] }, _id: { $ne: post._id } }) + .select('slug title score') + .sort('-score -date') + .limit(3) + .lean(); + + _relatedPosts = _relatedPosts.concat(posts); + } + + _relatedPosts.forEach((r) => { + r.userGenerated = false; // eslint-disable-line no-param-reassign + if (!relatedPosts.map(p => p._id.toString()).includes(r._id.toString())) relatedPosts.push(r); + }); + + relatedPosts.sort((a, b) => { + if (b) return b.score - a.score; + return 1; + }); + + // from saved by users + post.relatedPosts.forEach((r) => { + r.userGenerated = true; // eslint-disable-line no-param-reassign + if (!relatedPosts.map(p => p._id.toString()).includes(r._id.toString())) relatedPosts.push(r); + }); + + return res.json(relatedPosts); +} + +async function saveRelatedEpisode(req, res) { + const { post, params: { episodeSlug } } = req; + + if (!episodeSlug) return res.status(400).end('Missing data'); + + const newPost = await Post.findOne({ slug: episodeSlug }).select('slug'); + + if (!newPost) return res.status(404).end('Post not found'); + + if (post.relatedPosts.find(id => id.toString() === newPost._id.toString())) { + return res.status(400).end('Episode already included'); + } + + post.relatedPosts = post.relatedPosts.concat([newPost._id]); + + await post.save(); + + return res.status(201).end(); +} + +async function deleteRelatedEpisode(req, res) { + const { post, params: { episodeSlug } } = req; + + if (!episodeSlug) return res.status(400).end('Missing data'); + + const removePost = await Post.findOne({ slug: episodeSlug }).select('_id'); + + if (!removePost) return res.status(404).end('Post not found'); + + post.relatedPosts = post.relatedPosts.filter(p => p.toString() !== removePost._id.toString()); + + await post.save(); + + return res.status(200).end(); +} + +async function updateTopics(req, res) { + const { post, body: { topics } } = req; + + if (!topics) return res.status(400).end('Missing data'); + + const createTopics = topics.filter(t => !t._id); + const newTopics = topics.filter(t => t._id); + + if (newTopics.length) { + /* eslint-disable no-await-in-loop */ + for (let i = 0; i < createTopics.length; i += 1) { + const exist = await Topic.findOne({ name: new RegExp(createTopics[i].name, 'i') }); + if (exist) { + newTopics.push(exist); + } else { + const topic = new Topic({ name: createTopics[i].name, isUserGenerated: true }); + const saved = await topic.save(); + newTopics.push(saved); + } + } + } + + post.topics = newTopics.map(t => t._id.toString()); + + await post.save(); + + return res.json(newTopics); +} + export default { load, get, + popular, list, + search, recommendations, downvote, - upvote + upvote, + getRelatedEpisodes, + saveRelatedEpisode, + deleteRelatedEpisode, + updateTopics }; diff --git a/server/controllers/postSubscription.controller.js b/server/controllers/postSubscription.controller.js new file mode 100644 index 00000000..05441b8c --- /dev/null +++ b/server/controllers/postSubscription.controller.js @@ -0,0 +1,60 @@ +import Post from '../models/post.model'; +import PostSubscription from '../models/postSubscription.model'; +import { saveAndNotifyUser } from '../controllers/notification.controller'; + +async function getPostFromThread(entityId) { + return Post.findOne({ thread: entityId }).lean(); +} + +async function subscribePostFromEntity(entityId, user) { + const post = await getPostFromThread(entityId); + if (!post) return undefined; + subscribePost(post, user); + return post; +} + +async function notifyPostSubscribersFromEntity(entityId, user, payload, ignoreNotify) { + const post = await getPostFromThread(entityId); + if (!post) return; + await notifySubscribers(post, user, payload, ignoreNotify); +} + +async function subscribePost(post, user) { // Forumthread ID + const data = { + user: user._id, + post: post._id + }; + + const options = { + upsert: true, + setDefaultsOnInsert: true + }; + + await PostSubscription.findOneAndUpdate(data, data, options); + return post; +} + +async function notifySubscribers(post, user, payload, ignoreNotify = []) { + // get everyone that we need to notify + const users = await PostSubscription.find({ post: post._id }) + .where('user').ne(user._id) // ignore own user + .select('user') + .lean() + .exec() + .map(s => s.user); + + if (!users.length) return; + + // save and sends an update with all the latest notifications + users.forEach((u) => { + // ignoring users that already received a mention + if (!ignoreNotify.includes(u.toString())) saveAndNotifyUser(payload, u); + }); +} + +export default { + subscribePostFromEntity, + notifyPostSubscribersFromEntity, + subscribePost, + notifySubscribers +}; diff --git a/server/controllers/profile.controller.js b/server/controllers/profile.controller.js new file mode 100644 index 00000000..c9601320 --- /dev/null +++ b/server/controllers/profile.controller.js @@ -0,0 +1,35 @@ +import User from '../models/user.model'; +import { getActivityTree } from '../helpers/activity.helper'; + +const activityDays = process.env.NODE_ENV === 'production' ? 10 : 100; + +async function getPublic(req, res) { + const userId = req.params.profileId; + const user = await User.findById(userId) + .select('name lastName bio avatarUrl twitter website') + .lean() + .exec(); + + const activities = await getActivityTree(userId, activityDays); + + return res.status(200).send({ + user, + activities, + activityDays + }); +} + +async function getActivities(req, res) { + const { userId } = req.params; + const activities = await getActivityTree(userId, activityDays); + + return res.status(200).send({ + activities, + activityDays + }); +} + +export default { + getPublic, + getActivities +}; diff --git a/server/controllers/question.controller.js b/server/controllers/question.controller.js new file mode 100644 index 00000000..3a7bf4e7 --- /dev/null +++ b/server/controllers/question.controller.js @@ -0,0 +1,354 @@ +import async from 'async'; +import find from 'lodash/find'; +import isArray from 'lodash/isArray'; +import isNumber from 'lodash/isNumber'; +import shuffle from 'lodash/shuffle'; +import Question from '../models/question.model'; +import Topic from '../models/topic.model'; +import topicPageCtrl from './topicPage.controller'; +import { saveAndNotifyUser } from './notification.controller'; +import { mailTemplate } from '../helpers/mail'; + +async function get(req, res) { + const question = await Question + .findById(req.params.id) + .populate({ + path: 'answers', + populate: { + path: 'author', + select: 'name lastName avatarUrl twitter', + where: { + $or: [ + { deleted: false }, + { deleted: { $exists: false } } + ] + }, + } + }); + + if (!question) return res.status(404).send('Not found'); + + question.answers.sort((o1, o2) => { + return o1.votes.length >= o2.votes.length ? -1 : 1; + }); + + return res.json(question.toObject()); +} + +async function getUnanswered(req, res) { + let questions = await Question + .find({ + answers: { $size: 0 }, + $or: [ + { deleted: false }, + { deleted: { $exists: false } }, + ], + }) + .populate('author', 'name lastName email website avatarUrl bio'); + + if (!questions) { + return res.status(404).send('Not found'); + } + + questions = shuffle(questions) + .slice(0, parseInt(req.params.limit || 10, 10)); + + const topicIds = questions.map(q => q.entityId); + let topics = await Topic.find({ _id: { $in: topicIds } }); + + topics = topics + .map(t => ({ + ...t.toObject(), + _id: t._id.toString(), + })); + + questions = questions.map(q => ({ + topic: find(topics, { _id: q.entityId }), + ...q.toObject(), + })); + + return res.json(questions); +} + +async function create(req, res) { + const { + entityId, + entityType, + content, + questions, + startOrder = 0, + } = req.body; + + if (!entityId || !entityType || (!content && !questions)) { + return res.status(400).send('Missing data'); + } + + const author = req.user._id; + const series = []; + const saved = []; + let saveQuestions = []; + const topic = await Topic + .findOne({ _id: entityId }) + .populate('maintainers'); + + if (content) { + saveQuestions.push(content.trim()); + } + + if (questions) { + saveQuestions = questions.filter(q => !!q); + } + + saveQuestions.forEach((questionContent, index) => { + series.push((callback) => { + const question = new Question({ + author, + entityId, + entityType, + content: questionContent.trim(), + order: index + startOrder, + }); + + question.save() + .then((dbQuestion) => { + saved.push(dbQuestion); + callback(); + }) + .catch(callback); + }); + }); + + return async.series(series, (err) => { + if (err) { + return res.status(500).end(err.message ? err.message : err.toString()); + } + + if (entityType === 'topic') { + topicPageCtrl.createTopicPage(entityId); + } + + // Handle notifications + topic.maintainers = topic.maintainers || []; + topic.maintainers.forEach((maintainer) => { + const canSend = ( + maintainer && + req.user && + maintainer.email && + maintainer.email !== req.user.email + ); + + const qCount = (saveQuestions.length); + const payload = { + notification: { + title: `${qCount > 1 ? `${qCount} ` : ''}New question${qCount > 1 ? 's' : ''} asked about ${topic.name}`, + body: saveQuestions[0], + data: { + user: req.user.username, + mentioned: maintainer._id, + slug: topic.slug, + url: `/topic/${topic.slug}/question/${saved[0]._id}`, + } + }, + type: 'question', + entity: topic._id + }; + + if (canSend) { + // notify maintainer + saveAndNotifyUser(payload, maintainer._id); + + // email maintainer + mailTemplate.topicQuestion({ + to: maintainer.email, + subject: 'New question', + data: { + user: maintainer.name, + topic: topic.name, + actionLabel: qCount > 1 ? 'Go to topic' : 'Review question', + actionLink: `http://softwaredaily.com/topic/${topic.slug}${qCount > 1 ? '' : `/question/${saved[0]._id}`}`, + questions: saveQuestions, + } + }); + } + }); + + return res.json(saved.length === 1 ? saved[0] : saved); + }); +} + +async function getByEntity(req, res) { + const { entityType, entityId } = req.params; + const questions = await Question + .find({ + entityType, + entityId, + $or: [{ deleted: false }, { deleted: { $exists: false } }] + }) + .populate([ + { + path: 'author', + select: 'name lastName avatarUrl twitter', + }, + { + path: 'answers', + where: { $or: [{ deleted: false }, { deleted: { $exists: false } }] }, + populate: { + path: 'author', + select: 'name lastName avatarUrl twitter', + } + }, + ]) + .exec(); + + questions.forEach((question) => { + question.answers.sort((o1, o2) => { + return o1.votes.length >= o2.votes.length ? -1 : 1; + }); + }); + + questions.sort((a, b) => { + if (b.answers.length === a.answers.length) { + if (isNumber(a.order)) { + return a.order - b.order; + } + + return a.dateCreated - b.dateCreated; + } + + return b.answers.length - a.answers.length; + }); + + return res.json(questions); +} + +async function update(req, res) { + const { fullUser: user } = req; + const question = await Question.findById(req.params.id); + + if (!question) return res.status(404).send('Not found'); + + if (question.author && + (!user._id || !user.isAdmin || user._id.toString() !== question.author.toString())) { + return res.status(401).send('Not enough permissions to modify question'); + } + + if (!question.author && !user.isAdmin) { + return res.status(401).send('Not enough permissions to modify question'); + } + + Object.keys(req.body).forEach((key) => { + question[key] = typeof req.body[key] === 'string' ? req.body[key].trim() : req.body[key]; + }); + + question.dateUpdated = new Date(); + + try { + const saved = await question.save(); + return res.json(saved.toObject()); + } catch (e) { + return res.status(500).end(e.message ? e.message : e.toString()); + } +} + +function updateOrder(req, res) { + const { questions = [] } = req.body; + const series = []; + + questions.forEach((question, index) => { + series.push(async (callback) => { + try { + await Question + .updateOne( + { _id: question.id }, + { + $set: { + order: isNumber(question.order) ? question.order : index, + }, + }, + ); + } catch (e) { + console.error('Err updating question order: ', e); + } + + callback(); + }); + }); + + return async.series(series, (err) => { + if (err) { + return res.status(500).end(err.message ? err.message : err.toString()); + } + + return res.status(200).end('Saved'); + }); +} + +async function deleteQuestion(req, res) { + const { fullUser: user } = req; + const question = await Question.findById(req.params.id); + + if (!question) return res.status(404).send('Not found'); + + if (question.author && + (!user._id || !user.isAdmin || user._id.toString() !== question.author.toString())) { + return res.status(401).send('Not enough permissions to modify question'); + } + + if (!question.author && !user.isAdmin) { + return res.status(401).send('Not enough permissions to modify question'); + } + + question.deleted = true; + question.dateUpdated = new Date(); + + try { + const saved = await question.save(); + return res.json(saved.toObject()); + } catch (e) { + return res.status(500).end(e.message ? e.message : e.toString()); + } +} + +async function getRelated(req, res, next) { + if (!isArray(req.topicIds)) { + return next(); + } + + const questions = await Question + .find({ + entityId: { $in: req.topicIds }, + $or: [ + { deleted: false }, + { deleted: { $exists: false } }, + ], + }) + .sort('-dateUpdated') + .populate(['answers']) + .limit(20); + + questions.forEach((question) => { + question.answers.sort((a, b) => b.votes.length - a.votes.length); + }); + + questions.sort((a, b) => { + return (b.answers.length === a.answers.length) + ? b.dateCreated - a.dateCreated + : b.answers.length - a.answers.length; + }); + + req.response = req.response || {}; + req.response.questions = questions.slice(0, 10); + + return next(); +} + +export default { + get, + getUnanswered, + getByEntity, + getRelated, + create, + update, + updateOrder, + delete: deleteQuestion, +}; diff --git a/server/controllers/relatedLink.controller.js b/server/controllers/relatedLink.controller.js index c3880bdc..e2c85fc6 100644 --- a/server/controllers/relatedLink.controller.js +++ b/server/controllers/relatedLink.controller.js @@ -1,4 +1,11 @@ +import request from 'request'; +import { getMetadata } from 'page-metadata-parser'; +import jsdom from 'jsdom'; import RelatedLink from '../models/relatedLink.model'; +import TopicPage from '../models/topicPage.model'; +import Topic from '../models/topic.model'; + +const { JSDOM } = jsdom; /** * @swagger @@ -70,20 +77,53 @@ function remove(req, res, next) { * $ref: '#/responses/NotFound' */ -function create(req, res, next) { +async function create(req, res, next) { const { user } = req; - const { postId } = req.params; - const { url, title } = req.body; + const { postId, slug } = req.params; + const { url, type = 'link' } = req.body; + const options = { + url, + timeout: 15000, + headers: { + 'User-Agent': 'googlebot', + } + }; - const relatedLink = new RelatedLink(); - relatedLink.url = url; - relatedLink.title = title; - relatedLink.post = postId; - relatedLink.author = user._id; - relatedLink - .save() - .then(relatedLink1 => res.status(201).json(relatedLink1)) - .catch(err => next(err)); + let topic; + let topicPage; + let entityType = 'post'; + if (slug) { + topic = await Topic.findOne({ slug }).lean(); + topicPage = await TopicPage.findOne({ topic: topic._id }).lean(); + entityType = 'topic'; + } + + request(options, (error, reply, body) => { + if (error || !body || reply.statusCode !== 200) { + return next(error); + } + + const { document } = (new JSDOM(body)).window; + const relatedLink = new RelatedLink(); + const metadata = getMetadata(document, url); + + relatedLink.url = url; + relatedLink.title = metadata.title || url; + relatedLink.type = type; + relatedLink.entityType = entityType; + relatedLink.post = postId || undefined; + relatedLink.topicPage = (topicPage) ? topicPage._id : undefined; + relatedLink.author = user._id; + + if (metadata.icon) { + relatedLink.icon = metadata.icon; + } + + return relatedLink + .save() + .then(relatedLink1 => res.status(201).json(relatedLink1)) + .catch(err => next(err)); + }); } function list(req, res, next) { diff --git a/server/controllers/rss.controller.js b/server/controllers/rss.controller.js new file mode 100644 index 00000000..441611ed --- /dev/null +++ b/server/controllers/rss.controller.js @@ -0,0 +1,27 @@ +import { isActive } from './subscription.controller'; + +function publicFeedAll(req, res) { + res.setHeader('Content-Type', 'text/xml; charset=utf-8'); + res.status(200).send(req.app.get('rssFeedPublicAll')); +} + +function publicFeed(req, res) { + res.setHeader('Content-Type', 'text/xml; charset=utf-8'); + res.status(200).send(req.app.get('rssFeedPublic')); +} + +async function privateFeed(req, res) { + res.setHeader('Content-Type', 'text/xml; charset=utf-8'); + + const subscriptionId = Buffer.from(req.params.id, 'base64').toString('utf8'); + + if (!await isActive(subscriptionId)) return res.status(404).send(); + + return res.status(200).send(req.app.get('rssFeedPrivate')); +} + +export default { + publicFeedAll, + publicFeed, + privateFeed, +}; diff --git a/server/controllers/subscription.controller.js b/server/controllers/subscription.controller.js index af41fd04..921b270d 100644 --- a/server/controllers/subscription.controller.js +++ b/server/controllers/subscription.controller.js @@ -1,9 +1,18 @@ import httpStatus from 'http-status'; +import mongoose from 'mongoose'; import stripe from '../helpers/stripe.helper'; import APIError from '../helpers/APIError'; import Subscription from '../models/subscription.model'; import User from '../models/user.model'; +async function isActive(id) { + if (!id || typeof id !== 'string') return false; + if (!mongoose.Types.ObjectId.isValid(id)) return false; + const subscription = await Subscription.findById(id).lean(); + if (!subscription) return false; + return subscription.active; +} + function cancel(req, res, next) { if (req.fullUser && req.fullUser.subscription) { const { subscriptionId } = req.fullUser.subscription.stripe; @@ -151,4 +160,9 @@ function create(req, res, next) { return null; } -export default { create, cancel, subscriptionDeletedWebhook }; +export default { + create, + cancel, + subscriptionDeletedWebhook, + isActive +}; diff --git a/server/controllers/topic.controller.js b/server/controllers/topic.controller.js new file mode 100644 index 00000000..9395e6d0 --- /dev/null +++ b/server/controllers/topic.controller.js @@ -0,0 +1,661 @@ +import shuffle from 'lodash/shuffle'; +import isArray from 'lodash/isArray'; +import Topic from '../models/topic.model'; +import Job from '../models/job.model'; +import Post from '../models/post.model'; +import User from '../models/user.model'; +import TopicPage from '../models/topicPage.model'; +import { mailTemplate } from '../helpers/mail'; +import topicPageCtrl from './topicPage.controller'; + +/** + * @swagger + * tags: + * - name: topic + * description: Topics info and lists + */ + +/** + * @swagger + * parameters: + * topicId: + * name: topicId + * in: path + * description: Mongo ObjectId of topic + * required: true + * type: string + */ + +async function create(req, res) { + const { name, maintainer, isUserGenerated } = req.body; + const { user } = req; + + if (user.blockedTopicEdit) return res.status(400).send('Not enough permissions to create a topic'); + + const exist = await Topic.findOne({ name: new RegExp(`^${name}`, 'i') }); + if (exist) return res.status(400).send(`A ${name} Topic already exists`); + + const topic = new Topic(); + + topic.name = name; + if (maintainer) topic.maintainers = [maintainer]; + if (isUserGenerated) topic.isUserGenerated = isUserGenerated; + + if (req.body.postId) { + topic.postCount = 1; + const topicId = topic._id.toString(); + Post.findByIdAndUpdate(req.body.postId, { $push: { topics: topicId } }, async (err) => { + if (err) { + throw err; + } + }); + } + + return topic + .save() + .then((topicSaved) => { + res.status(201).json(topicSaved); + }) + .catch(err => res.status(500).json(err.errmsg)); +} + +async function add(req, res) { + const exist = await Topic.findOne({ name: req.body.data.name }); + if (exist) return res.status(400).send(`A ${req.body.data.name} Topic already exists`); + const topic = new Topic(req.body.data); + return topic + .save() + .then((topicSaved) => { + res.status(201).json(topicSaved); + }) + .catch(err => res.status(400).send(err.errmsg)); +} + +async function get(req, res) { + const topic = await Topic + .findById(req.params.topicId) + .populate('maintainers', 'name lastName email website avatarUrl isAdmin bio blockedTopicEdit'); + + res.send(topic); +} + +async function getFull(req, res) { + const topics = await Topic.find() + .populate('maintainers', 'name lastName email website avatarUrl isAdmin bio'); + res.send(topics); +} + +function top(req, res) { + Topic + .find({ + status: 'active', + $or: [ + { maintainers: { $size: 0 } }, + { maintainers: { $exists: false } }, + ] + }) + .sort({ postCount: -1 }) + .limit(parseInt(req.params.count, 10)) + .then((topics) => { + res.send(topics); + }) + .catch((err) => { + res.status(500).send({ + message: err.message || 'Some error occurred while retrieving topics.' + }); + }); +} + +/* eslint-disable consistent-return */ +async function removeMaintainer(req, res) { + const { topicSlug: slug, event } = req.body; + const { user } = req; + + try { + await Topic + .updateOne( + { slug }, + { + $pullAll: { + maintainers: [ + user._id + ] + } + } + ); + + res.end('Saved'); + + // Update history + const topic = await Topic.findOne({ slug }); + + if (topic) { + const topicPage = await topicPageCtrl.createTopicPage(topic._id); + + topicPage.history = topicPage.history.concat(new TopicPage.History({ + user: user._id, + event + })); + + await topicPage.save(); + } + } catch (e) { + return res.status(500).json(e); + } + + if (!res.headersSent) { + return res.end('Saved'); + } +} + +async function setMaintainer(req, res) { + const { topicSlug, event } = req.body; + const { user } = req; + const topic = await Topic.findOne({ slug: topicSlug }); + + if (!topic) { + return res.status(404).send('Topic not found'); + } + + topic.maintainers = topic.maintainers || []; + + if (topic.maintainers.indexOf(user._id) >= 0) { + return res.status(400).send('You are already a maintainer'); + } + + topic.maintainers = topic.maintainers.concat(user._id); + + await topic.save(); + + const topicPage = await topicPageCtrl.createTopicPage(topic._id); + + topicPage.history = topicPage.history.concat(new TopicPage.History({ + user: user._id, + event + })); + + await topicPage.save(); + + return res.end('Saved'); + + // const admins = await User.find({ isAdmin: true }).lean().exec(); + + // return admins.forEach((admin) => { + // mailTemplate.topicNewMaintainer({ + // to: admin.email, + // subject: `New topic maintainer - ${topic.name}`, + // data: { + // user: admin.name, + // maintainer: `${user.name} ${user.lastName || ''}`, + // email: user.email, + // topic: topic.name, + // } + // }); + // }); +} + +async function episodes(req, res) { + const topic = await Topic.findOne({ slug: req.params.slug }); + if (!topic) return res.status(404).send('No topic found'); + + const eps = await Post.find({ topics: { $in: [topic._id.toString()] } }) + .select('slug title') + .sort('-date') + .lean() + .exec(); + + return res.json({ episodes: eps.slice(0, 10), total: eps.length }); +} + +async function jobs(req, res) { + const topic = await Topic.findOne({ slug: req.params.slug }); + + if (!topic) return res.status(404).send('No topic found'); + + const _jobs = await Job + .find({ + isDeleted: false, + topics: { + $in: [topic._id.toString()] + } + }) + .select('slug title') + .lean() + .exec(); + + return res.json({ + jobs: shuffle(_jobs).slice(0, 5), + total: _jobs.length, + }); +} + +async function createRelatedEpisode(req, res) { + const { postSlug } = req.body; + + if (!postSlug) return res.status(400).send('Missing data'); + + const topic = await Topic.findOne({ slug: req.params.slug }); + if (!topic) return res.status(404).send('No topic found'); + + const post = await Post.findOne({ slug: postSlug }).select('topics'); + if (!post) return res.status(404).send('Episode not found'); + + // post already has topic + const existingTopic = post.topics.find(t => t === topic._id.toString()); + if (existingTopic) return res.status(400).send('Episode already has this topic'); + + post.topics = post.topics.concat(topic._id.toString()); + + try { + await post.save(); + return res.status(201).end(); + } catch (e) { + return res.status(500).json(e); + } +} + +async function index(req, res) { + if (req.query.userId) { + const user = await User.findById(req.query.userId); + + Topic.find({ _id: { $in: user.topics }, status: 'active' }) + .then((topics) => { + res.send(topics); + }).catch((err) => { + res.status(500).send({ + message: err.message || 'Some error occurred while retrieving topics.' + }); + }); + } else if (req.query.postId) { + const post = await Post.findById(req.query.postId); + + Topic.find({ _id: { $in: post.topics }, status: 'active' }) + .then((topics) => { + res.send(topics); + }).catch((err) => { + res.status(500).send({ + message: err.message || 'Some error occurred while retrieving topics.' + }); + }); + } else { + Topic.find({ status: 'active' }) + .then((topics) => { + res.send(topics); + }).catch((err) => { + res.status(500).send({ + message: err.message || 'Some error occurred while retrieving topics.' + }); + }); + } +} + +function searchTopics(req, res) { + const { search } = req.query; + Topic.find({ name: { $regex: RegExp(`^.*${search}.*$`), $options: 'i' }, status: 'active' }) + .then((topics) => { + res.send(topics); + }).catch((err) => { + res.status(500).send({ + message: err.message || 'Some error occurred while retrieving topics.' + }); + }); +} + +function mostPopular(req, res) { + Topic.find({ status: 'active' }).sort({ postCount: -1 }).limit(10) + .then((topics) => { + res.send(topics); + }) + .catch((err) => { + res.status(500).send({ + message: err.message || 'Some error occurred while retrieving topics.' + }); + }); +} + +function mostPosts(req, res) { + Topic.find({ status: 'active' }).sort({ postCount: -1 }).limit(40) + .populate('topicPage', 'published') + .then((topics) => { + const result = topics.filter((topic) => { + return !topic.topicPage || topic.status !== 'active'; + }); + res.send(result.slice(0, 10)); + }) + .catch((err) => { + res.status(500).send({ + message: err.message || 'Some error occurred while retrieving topics.' + }); + }); +} + +// old, still used in mobile? +function show(req, res) { + Topic.find({ slug: req.params.slug }, async (err, topic) => { + if (err) return; + // const posts = await Post.find({ topics: { $in: [topic[0]._id.toString()] } }); + + const { + limit = null, + createdAtBefore = null, + createdAfter = null + } = req.query; + + const query = {}; + if (limit) query.limit = limit; + if (createdAtBefore) query.createdAtBefore = createdAtBefore; + if (createdAfter) query.createdAfter = createdAfter; + if (isArray(topic) && topic[0] && topic[0]._id) query.topic = [topic[0]._id.toString()]; + + const posts = await Post.list(query); + + // manually populate (as Post can't have a reference to topic in model right now) + const topicsIds = posts.reduce((arr, post) => { + post.topics.forEach((t) => { + if (!arr.includes(t)) arr.push(t); + }); + return arr; + }, []); + + const topics = await Topic.find({ _id: { $in: topicsIds } }) + .select('name slug') + .lean() + .exec(); + + posts.forEach((post) => { + post.topics = post.topics.map((postTopic) => { // eslint-disable-line no-param-reassign + return topics.find(t => t._id.toString() === postTopic); + }); + }); + + const body = { + topic, + posts + }; + res.send(body); + }); +} + +async function update(req, res) { + const data = req.body; + + const topic = await Topic.findById(req.params.topicId).lean().exec(); + + if (!topic) return res.status(404).send('Topic not found'); + + data.maintainers = data.maintainers || []; + topic.maintainers = topic.maintainers || []; + + return Topic.findByIdAndUpdate(req.params.topicId, { $set: data }, (err) => { + if (err) { + return; + } + + res.send('Topic updated.'); + + data.maintainers.forEach((maintainer) => { + if (!topic.maintainers.filter(m => m.toString() === maintainer._id).length) { + mailNewMaintainer(topic, maintainer); + } + }); + }); +} + +async function mailNewMaintainer(topic, maintainerId) { + const user = await User.findById(maintainerId); + + if (!user) return; + + const topicLink = `http://softwaredaily.com/topic/${topic.slug}/edit`; + + const send = mailTemplate.topicMaintainer({ + to: user.email, + subject: 'New topic maintainer!', + data: { user: user.name, topic: topic.name, topicLink } + }); + + if (!send) { + console.error('[mailTemplate] Send e-mail failed!'); // eslint-disable-line + } +} + +async function deleteTopic(req, res) { + const { user } = req.body; + const userById = await User.findOne({ _id: [user.id] }); + + if (userById && userById.isAdmin) { + Topic.findByIdAndUpdate(req.params.id, { $set: { status: 'deleted' } }, (err) => { + if (err) return; + res.send('Topic deleted.'); + }); + } else { + res.send('Only admin can delete topic.'); + } +} + +async function addTopicsToUser(req, res) { + try { + const { topics } = req.body; + const { userId } = req.body; + + if (userId) { + const user = await User.findById(userId); + + const filteredTopics = []; + topics.map((t) => { + if (!user.topics.includes(t)) { + filteredTopics.push(t); + } + return filteredTopics; + }); + const removeTopics = []; + user.topics.map((t) => { + if (!topics.includes(t)) { + removeTopics.push(t); + } + return removeTopics; + }); + User.findByIdAndUpdate( + userId, + { + $push: { + topics: { $each: filteredTopics } + } + }, async (err) => { + if (err) return; + User.findByIdAndUpdate( + userId, + { + $pull: { + topics: { $in: removeTopics } + } + }, async (error) => { + if (error) return; + res.send('Topic added.'); + } + ); + } + ); + } + } catch (e) { + res.status(400).send('error'); + } +} + +async function addTopicsToPost(req, res) { + try { + const { postId } = req.body; + const { topics } = req.body; + + if (postId) { + const post = await Post.findById(postId); + + const filteredTopics = []; + topics.map((t) => { + if (!post.topics.includes(t)) { + filteredTopics.push(t); + } + return filteredTopics; + }); + + const removeTopics = []; + post.topics.map((t) => { + if (!topics.includes(t)) { + removeTopics.push(t); + } + return removeTopics; + }); + Post.findByIdAndUpdate( + postId, + { + $push: { + topics: { $each: filteredTopics } + } + }, async (err) => { + if (err) return; + filteredTopics.map((topicId) => { + Topic.findByIdAndUpdate(topicId, { + $inc: { postCount: 1 } + }, (error) => { + if (error) throw error; + }); + return true; + }); + Post.findByIdAndUpdate( + postId, + { + $pull: { + topics: { $in: removeTopics } + } + }, async (error) => { + if (error) return; + removeTopics.map((topicId) => { + Topic.findByIdAndUpdate(topicId, { + $inc: { postCount: -1 } + }, (removeTopicError) => { + if (removeTopicError) throw removeTopicError; + }); + return true; + }); + } + ); + res.send('Topic added.'); + } + ); + } else { + res.status(400).send('postId is necessary.'); + } + } catch (e) { + res.status(400).send(e); + } +} + +/** + * @swagger + * /topics: + * post: + * summary: Create new topic + * description: Create new topic by current user. + * tags: [topic] + * security: + * - Token: [] + * responses: + * '200': + * description: successful operation + * schema: + * type: array + * items: + * $ref: '#/definitions/Post' + * get: + * summary: Get topics index + * description: Get list of topics. If user_id exist in query params return topics by user_id. + * tags: [topic] + * security: + * - Token: [] + * responses: + * '200': + * description: successful operation + * schema: + * type: array + * items: + * $ref: '#/definitions/Post' + * + * /topics/addTopicToUser: + * post: + * summary: Add topic to user + * description: Adds topic to topics array at user document. + * tags: [topic] + * security: + * - Token: [] + * responses: + * '200': + * description: successful operation + * schema: + * type: array + * items: + * $ref: '#/definitions/Post' + * + * /topics/{topicId}: + * get: + * summary: Get topic + * description: Get topic by id. + * tags: [topic] + * security: + * - Token: [] + * responses: + * '200': + * description: successful operation + * schema: + * type: array + * items: + * $ref: '#/definitions/Post' + * update: + * summary: Update topic + * description: Update topic by id. + * tags: [topic] + * security: + * - Token: [] + * responses: + * '200': + * description: successful operation + * schema: + * type: array + * items: + * $ref: '#/definitions/Post' + * delete: + * summary: Delete topic + * description: Delete topic by id. Need user.id in req.body to check if the user is an admin. + * tags: [topic] + * security: + * - Token: [] + * responses: + * '200': + * description: successful operation + * schema: + * type: array + * items: + * $ref: '#/definitions/Post' + * + */ + +export default { + add, + get, + getFull, + top, + setMaintainer, + removeMaintainer, + create, + episodes, + jobs, + createRelatedEpisode, + index, + mostPopular, + mostPosts, + show, + update, + deleteTopic, + addTopicsToUser, + addTopicsToPost, + searchTopics +}; diff --git a/server/controllers/topicPage.controller.js b/server/controllers/topicPage.controller.js new file mode 100644 index 00000000..8e9b2d0d --- /dev/null +++ b/server/controllers/topicPage.controller.js @@ -0,0 +1,450 @@ +import mongoose from 'mongoose'; +import algoliasearch from 'algoliasearch'; +import every from 'lodash/every'; +import omit from 'lodash/omit'; +import flatten from 'lodash/flatten'; +import httpStatus from 'http-status'; +import Topic from '../models/topic.model'; +import TopicPage from '../models/topicPage.model'; +import Question from '../models/question.model'; +import RelatedLink from '../models/relatedLink.model'; +import { signS3 } from '../helpers/s3'; +import config from '../../config/config'; +import { mailTemplate } from '../helpers/mail'; +import User from '../models/user.model'; +import topicPageRevisionCtrl from './topicPageRevision.controller'; + +async function indexTopic(topicId) { + const client = algoliasearch( + process.env.ALGOLIA_APP_ID, + process.env.ALGOLIA_API_KEY, + ); + + const index = client.initIndex(process.env.ALGOLIA_TOPICS_INDEX); + + const topicPage = await TopicPage + .findOne({ topic: topicId }) + .populate('topic'); + + const questions = await Question + .find({ entityId: topicId }) + .populate('answers'); + + let answers = questions + .filter(q => q.answers.length) + .map((q) => { + return q.answers.map(a => a.content); + }); + + answers = flatten(answers); + + const _topicPage = topicPage.toObject(); + const slug = (_topicPage.topic && _topicPage.topic.slug) ? _topicPage.topic.slug : ''; + const objectID = _topicPage.searchIndex; + const updateObject = { + ...omit(_topicPage, [ + 'history', + '__v', + 'images', + 'searchIndex', + ]), + slug, + answers, + }; + + if (updateObject.topic && updateObject.topic.name) { + updateObject.topic = updateObject.topic.name; + updateObject._title = updateObject.topic; + } + + if (objectID) { + updateObject.objectID = objectID; // eslint-disable-line + } + + index + [objectID ? 'saveObject' : 'addObject'](updateObject) // eslint-disable-line + .then(({ objectID }) => { // eslint-disable-line + topicPage.searchIndex = objectID; + topicPage.save(); + }); + + return Promise.resolve(); +} + +function checkMaintainer(req, topic) { + const maintainers = topic.maintainers || []; + const hasMaintainers = (maintainers.length > 0 && every(maintainers, '_id')); + const hasUser = (req.user && req.user._id); + + return ( + hasUser && + hasMaintainers && + maintainers.filter(m => req.user._id.toString() === m._id.toString()).length + ); +} + +async function createTopicPage(topicId) { + let topicPage = await TopicPage.findOne({ topic: topicId }) + .populate('history.user', 'name avatarUrl isAdmin'); + + if (!topicPage) { + const topic = await Topic.findById(topicId); + + if (!topic) return false; + + topicPage = new TopicPage({ + topic: topicId, + content: '' + }); + + const saved = await topicPage.save(); + topic.topicPage = topicPage._id; + await topic.save(); + return saved; + } + + return topicPage; +} + +async function get(req, res) { + if (req.fullUser.blockedTopicEdit) { + return res.status(400).send('Not enough permissions to edit this page'); + } + + const options = { + $or: [{ slug: req.params.slug }] + }; + + if (mongoose.Types.ObjectId.isValid(req.params.slug)) { + options.$or.push({ _id: req.params.slug }); + } + + const topic = await Topic + .findOne(options) + .populate('maintainers', 'name lastName email website twitter avatarUrl isAdmin bio dateUpdated'); + + if (!topic) { + return res.status(404).send(`Topic ${req.params.slug} not found`); + } + + let topicPage = await TopicPage.findOne({ topic: topic._id }) + .populate('history.user', 'name avatarUrl isAdmin'); + + let status = 200; + + if (!topicPage) { + topicPage = await createTopicPage(topic._id); + status = 201; + } + + const revisions = await topicPageRevisionCtrl.getAll(topicPage._id); + + return res.status(status).send({ topic, topicPage, revisions }); +} + +async function update(req, res, updateRevision = true) { + const { fullUser: user } = req; + if (user.blockedTopicEdit) return res.status(400).send('Not enough permissions to edit this page'); + + const topic = await Topic.findOne({ slug: req.params.slug }) + .populate('maintainers', 'name lastName email avatarUrl isAdmin'); + + if (!topic) return res.status(404).send(`Topic ${req.params.slug} not found`); + + const topicPage = await TopicPage.findOne({ topic: topic._id }); + + if (!topicPage) return res.status(404).send(`Topic Page ${req.params.slug} not found`); + + if (!checkMaintainer(req, topic) && !user.isAdmin) return res.status(403).send('Not authorized'); + + if (!topicPage.lastRevision) { + // secure old content for new revision schemma + await topicPageRevisionCtrl.create(topicPage, user); + topicPage.revision = 1; + topicPage.lastRevision = 1; + } + + const changedPublished = topicPage.published !== req.body.published; + + if (req.body.content) topicPage.content = req.body.content; + if (req.body.logo) topicPage.logo = req.body.logo; + if (req.body.twitterAccounts) topicPage.twitterAccounts = req.body.twitterAccounts; + + topicPage.published = req.body.published || false; + + topic.topicPage = topicPage._id; + + try { + if (updateRevision) { + const topicPageRevision = await topicPageRevisionCtrl.create(topicPage, user); + if (topicPageRevision) { + topicPage.revision = topicPageRevision.revision; + topicPage.lastRevision = topicPageRevision.revision; + } + } + + topicPage.history = topicPage.history.concat(new TopicPage.History({ + user: user._id, + event: req.body.event, + revision: topicPage.revision + })); + + await topic.save(); + await topicPage.save(); + + if (req.body.published !== undefined && changedPublished) { + mailAdminsPublish(topicPage, topic, user); + } + } catch (e) { + return res.status(404).send(`Error saving: ${e.message || e}`); + } + + // Let's not wait on this to respond + if (topicPage.content && topicPage.published) { + indexTopic(topic._id); + } + + return res.status(200).send('Saved'); +} + +async function publish(req, res) { + req.body.event = 'publish'; + req.body.published = true; + + update(req, res, false); +} + +async function unpublish(req, res) { + req.body.event = 'unpublish'; + req.body.published = false; + + update(req, res, false); +} + +async function mailAdminsPublish(topicPage, topic, user) { + const admins = await User.find({ isAdmin: true }).lean().exec(); + + if (!admins.length) return; + + admins.forEach((admin) => { + mailTemplate.topicPublish({ + to: admin.email, + subject: 'New topic publish status', + data: { + user: admin.name, + maintainer: `${user.name} ${user.lastName}`, + publish: (topicPage.published) ? 'Published' : 'Unpublished', + topicPage: topic.name, + topicLink: `http://softwaredaily.com/topic/${topic.slug}` + } + }); + }); +} + +async function showContent(req, res) { + const options = { + $or: [{ slug: req.params.slug }] + }; + + if (mongoose.Types.ObjectId.isValid(req.params.slug)) { + options.$or.push({ _id: req.params.slug }); + } + + const topic = await Topic + .findOne(options) + .populate('maintainers', 'name lastName email website twitter avatarUrl isAdmin bio dateUpdated'); + + if (!topic) { + return res.status(404).send(`Topic ${req.params.slug} not found`); + } + + const topicPage = await TopicPage.findOne({ topic: topic._id }); + + return res.status(200).json({ topic, topicPage }); +} + +async function relatedLinks(req, res) { + const { slug } = req.params; + const topic = await Topic.findOne({ slug }); + const topicPage = await TopicPage.findOne({ topic: topic._id }); + + RelatedLink.list({ topicPage: topicPage._id, user: req.user }) + .then((links) => { + res.json(links); + }); +} + +async function getImages(req, res) { + const { slug } = req.params; + const topic = await Topic.findOne({ slug }); + + if (!topic) { + return res.json([]); + } + + const topicPage = await TopicPage.findOne({ topic: topic._id }) + .lean() + .exec(); + + if (!topicPage) { + return res.json([]); + } + + const images = topicPage.images.filter(img => !img.deleted); + + return res.json(images); +} + +async function signS3ImageUpload(req, res) { + const { fileType } = req.body; + const randomNumberString = `${Math.random()}`; + const type = getFileType(fileType); + const newFileName = `topic_images/${randomNumberString.replace('.', '_')}${type}`; + + const cbSuccess = (result) => { + createImage(req, res, result); + }; + + // eslint-disable-next-line + const cbError = err => { + if (err) { + console.log(err); // eslint-disable-line + return res.status(httpStatus.SERVICE_UNAVAILABLE).send('There was a problem getting a signed url'); + } + }; + signS3(config.aws.topicBucketName, fileType, newFileName, cbSuccess, cbError); +} + +async function createImage(req, res, result) { + const { slug } = req.params; + const topic = await Topic.findOne({ slug }); + const image = new TopicPage.Image({ + user: req.user._id, + url: result.url, + }); + + await TopicPage.update({ topic: topic._id }, { + $push: { + images: { $each: [image], $position: 0 } + } + }); + + res.write(JSON.stringify(result)); + res.end(); +} + +const types = [ + { type: 'image/png', fileType: '.png' }, + { type: 'image/gif', fileType: '.gif' }, + { type: 'image/jpeg', fileType: '.jpg' } +]; + +function getFileType(fileType) { + const type = types.find(t => t.type === fileType); + return type ? type.fileType : ''; +} + +async function signS3LogoUpload(req, res) { + const { fileType } = req.body; + const randomNumberString = `${Math.random()}`; + const type = getFileType(fileType); + const newFileName = `topic_images/${randomNumberString.replace('.', '_')}${type}`; + + const cbSuccess = (result) => { + changeLogo(req, res, result); + }; + + // eslint-disable-next-line + const cbError = err => { + if (err) { + console.log(err); // eslint-disable-line + return res.status(httpStatus.SERVICE_UNAVAILABLE).send('There was a problem getting a signed url'); + } + }; + signS3(config.aws.topicBucketName, fileType, newFileName, cbSuccess, cbError); +} + +async function changeLogo(req, res, result) { + const { slug } = req.params; + const topic = await Topic.findOne({ slug }); + + const topicPage = await TopicPage.findOne({ topic: topic._id }); + + if (topicPage) { + topicPage.logo = result.url; + + if (!topicPage.lastRevision) { + // secure old content for new revision schemma + await topicPageRevisionCtrl.create(topicPage, req.user); + topicPage.revision = 1; + topicPage.lastRevision = 1; + } + + const topicPageRevision = await topicPageRevisionCtrl.create(topicPage, req.user); + if (topicPageRevision) { + topicPage.revision = topicPageRevision.revision; + topicPage.lastRevision = topicPageRevision.revision; + } + + topicPage.history = topicPage.history.concat(new TopicPage.History({ + user: req.user._id, + event: 'editLogo', + revision: topicPage.revision + })); + + await topicPage.save(); + } + + res.write(JSON.stringify(result)); + res.end(); +} + +async function deleteImage(req, res) { + const { slug, imageId } = req.params; + const topic = await Topic.findOne({ slug }); + const topicPage = await TopicPage.findOne({ topic: topic._id }); + + const image = topicPage.images.find(img => img._id.toString() === imageId.toString()); + + if (!image) return res.status(404).send('Image not found'); + + image.deleted = true; + + await topicPage.save(); + + return res.send('Deleted'); +} + +async function recentPages(req, res) { + const topicPages = await TopicPage.find() + .sort('-dateUpdated') + .populate('topic', 'maintainer status name slug') + .limit(50); + + const result = topicPages.filter((topicPage) => { + return topicPage.topic && topicPage.published; + }).map((topicPage) => { + return { + name: topicPage.topic.name, + slug: topicPage.topic.slug + }; + }); + + res.json(result.slice(0, 30)); +} + +export default { + get, + createTopicPage, + update, + publish, + unpublish, + showContent, + relatedLinks, + getImages, + signS3ImageUpload, + signS3LogoUpload, + deleteImage, + recentPages, + indexTopic, +}; diff --git a/server/controllers/topicPageRevision.controller.js b/server/controllers/topicPageRevision.controller.js new file mode 100644 index 00000000..bcbb1eb3 --- /dev/null +++ b/server/controllers/topicPageRevision.controller.js @@ -0,0 +1,116 @@ + +import every from 'lodash/every'; +import Topic from '../models/topic.model'; +import TopicPage from '../models/topicPage.model'; +import TopicPageRevision from '../models/topicPageRevision.model'; + +function checkMaintainer(req, topic) { + const maintainers = topic.maintainers || []; + const hasMaintainers = (maintainers.length > 0 && every(maintainers, '_id')); + const hasUser = (req.user && req.user._id); + + return ( + hasUser && + hasMaintainers && + maintainers.filter(m => req.user._id.toString() === m._id.toString()).length + ); +} + +async function create(topicPage, user) { + const revision = new TopicPageRevision({ + topicPage: topicPage._id, + author: user._id, + content: topicPage.content, + logo: topicPage.logo, + revision: topicPage.lastRevision ? topicPage.lastRevision + 1 : 1, + }); + + const saved = await revision.save(); + return saved; +} + +async function getAll(topicPageId) { + const revisions = await TopicPageRevision.find({ topicPage: topicPageId }) + .select('author revision dateCreated topicPage') + .populate('author', 'name lastName avatarUrl'); + + revisions.sort((a, b) => { + if (!b) return -1; + return b.dateCreated - a.dateCreated; + }); + + return revisions; +} + +async function get(req, res) { + const { revisionNumber, slug } = req.params; + + const topic = await Topic.findOne({ slug }).select('topicPage'); + + if (!topic) { + return res.status(404).send(`Topic ${slug} not found`); + } + + const revision = await TopicPageRevision.findOne({ + topicPage: topic.topicPage, + revision: revisionNumber + }) + .populate('author', 'name lastName avatarUrl'); + + return res.json(revision); +} + +async function set(req, res) { + const { fullUser: user } = req; + const { revisionNumber, slug } = req.params; + + try { + const topic = await Topic.findOne({ slug }) + .select('topicPage maintainers') + .populate('maintainers', '_id'); + + if (!topic) { + return res.status(404).send(`Topic ${slug} not found`); + } + + if (!checkMaintainer(req, topic) && !user.isAdmin) return res.status(403).send('Not authorized'); + + const revision = await TopicPageRevision.findOne({ + topicPage: topic.topicPage, + revision: revisionNumber + }); + + if (!revision) { + return res.status(404).send(`Revision number (${revisionNumber}) not found`); + } + + const topicPage = await TopicPage.findById(topic.topicPage); + + if (!topicPage) { + return res.status(404).send('Topic Page not found'); + } + + topicPage.revision = revision.revision; + topicPage.content = revision.content; + topicPage.logo = revision.logo; + + topicPage.history = topicPage.history.concat(new TopicPage.History({ + user: req.user._id, + event: 'revisionRecover', + revision: revision.revision + })); + + await topicPage.save(); + + return res.end('Saved'); + } catch (e) { + return res.status(500).end(e.message ? e.message : e.toString()); + } +} + +export default { + create, + getAll, + get, + set +}; diff --git a/server/controllers/topicPageSubscription.controller.js b/server/controllers/topicPageSubscription.controller.js new file mode 100644 index 00000000..98a2c7aa --- /dev/null +++ b/server/controllers/topicPageSubscription.controller.js @@ -0,0 +1,48 @@ +import TopicPage from '../models/topicPage.model'; +import TopicSubscription from '../models/topicSubscription.model'; +import { saveAndNotifyUser } from '../controllers/notification.controller'; + +async function getTopic(entityId) { + const topicPage = await TopicPage.findOne({ _id: entityId }) + .populate('topic') + .exec(); + return topicPage.topic; +} + +async function subscribeTopicPage(entityId, user) { + const data = { + user: user._id, + topic: entityId + }; + + const options = { + upsert: true, + setDefaultsOnInsert: true + }; + + await TopicSubscription.findOneAndUpdate(data, data, options); + return getTopic(entityId); +} + +async function notifySubscribers(entityId, user, payload, ignoreNotify = []) { + // get everyone that we need to notify + const users = await TopicSubscription.find({ topic: entityId }) + .where('user').ne(user._id) // ignore own user + .select('user') + .lean() + .exec() + .map(s => s.user); + + if (!users.length) return; + + // save and sends an update with all the latest notifications + users.forEach((u) => { + // ignoring users that already received a mention + if (!ignoreNotify.includes(u.toString())) saveAndNotifyUser(payload, u); + }); +} + +export default { + subscribeTopicPage, + notifySubscribers +}; diff --git a/server/controllers/twitter.controller.js b/server/controllers/twitter.controller.js new file mode 100644 index 00000000..4c99b2b8 --- /dev/null +++ b/server/controllers/twitter.controller.js @@ -0,0 +1,43 @@ +import Twitter from 'twitter-lite'; + +const client = new Twitter({ + access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY, + access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET, + consumer_key: process.env.TWITTER_CONSUMER_KEY, + consumer_secret: process.env.TWITTER_CONSUMER_SECRET, +}); + +/** + * Get users search + * @returns {[Users]} + */ +async function usersSearch(req, res) { + const { q = '' } = req.query; + + if (!q) { + return res.json([]); + } + + try { + let results = await client.get('users/search', { q }); + + results = results.map(r => ({ + name: r.screen_name, + label: `@${r.screen_name}`, + displayName: r.name, + screen_name: r.screen_name, + })); + + return res.json(results); + } catch (err) { + return res + .status(500) + .send({ + message: err.message ? err.message : err, + }); + } +} + +export default { + usersSearch, +}; diff --git a/server/controllers/user.controller.js b/server/controllers/user.controller.js index e97c0888..e4b5cac8 100644 --- a/server/controllers/user.controller.js +++ b/server/controllers/user.controller.js @@ -7,6 +7,9 @@ import Favorite from '../models/favorite.model'; import User from '../models/user.model'; import PasswordReset from '../models/passwordReset.model'; import config from '../../config/config'; +import { getPrivateRss } from '../helpers/rss.helper'; +import searchParser from '../helpers/searchParser.helper'; +import Topic from '../models/topic.model'; const sgMail = require('@sendgrid/mail'); // TODO: move this out of here, probably in it's own file: @@ -48,6 +51,7 @@ function me(req, res, next) { User.get(req.user._id) .then((user) => { user.password = null; // eslint-disable-line + user.rss = getPrivateRss(user); // eslint-disable-line return res.json(user); }) .catch(e => next(e)); @@ -64,9 +68,6 @@ function get(req, res) { return res.json(user); } -// Bucket name: -// sd-profile-pictures - /** * Update existing user * @property {string} req.body.username - The username of user. @@ -74,9 +75,8 @@ function get(req, res) { * @returns {User} */ // eslint-disable-next-line -function update(req, res, next) { +function updateProfile(req, res, next) { const user = req.userLoaded; - const { username } = req.body; const avatarWasSet = req.body.isAvatarSet; // We gotta check a few things: // First we make sure we are the actual user we are modifying. @@ -86,30 +86,34 @@ function update(req, res, next) { 'Not enough permissions to modify that user.', httpStatus.UNAUTHORIZED, true - ); //eslint-disable-line + ); return next(err); } // Next we are making sure the username doens't already exist: - User.findOne({ username }) + User.findById(user.id) .exec() .then((_user) => { - // eslint-disable-next-line - if (_user && _user.id != user.id) { - let err = new APIError('User already exists.', httpStatus.UNAUTHORIZED, true); //eslint-disable-line + if (!_user) { + const err = new APIError( + 'User not found.', + httpStatus.NOT_FOUND, + true + ); return next(err); } + // Using _.pick to only get a few properties: // otherwise user can set themselves to verified, etc :) const newValues = _.pick(req.body, User.updatableFields); Object.assign(user, newValues); if (avatarWasSet) { - // This should be pulled from utils: - const S3_BUCKET = 'sd-profile-pictures'; - user.avatarUrl = `https://${S3_BUCKET}.s3.amazonaws.com/${user._id}`; + const S3_BUCKET = config.aws.profilePicBucketName; + // timestamp to force browser update. This will force a new browser cache + user.avatarUrl = `https://${S3_BUCKET}.s3.amazonaws.com/${user._id}?${Date.now()}`; } return user.save().then((newUser) => { - const userMinusPassword = Object.assign({}, newUser, { password: null }); + const userMinusPassword = Object.assign({}, newUser.toObject(), { password: null }); res.json(userMinusPassword); }); }) @@ -189,7 +193,7 @@ function requestPasswordReset(req, res, next) { // TODO: throttle how many emails we send to same email per time. const msg = { to: email, - from: 'no-reply@softwaredaily.com', + from: config.email.fromAddress, subject: 'Password reset email', text: `Reset your password here ${config.baseUrl}/#/regain-account/${secretKey}/${ resetPass._id @@ -209,26 +213,87 @@ function requestPasswordReset(req, res, next) { }); } +async function getAll(req, res, next) { + try { + const query = User.find(); + + const users = await query + .where('name').ne('Software Engineer') + .select('-password') + .exec(); + + const filtered = users.filter((user) => { + return !/(Software Developer-)/.test(user); + }); + + return res.json(filtered); + } catch (err) { + return next(err); + } +} + +async function adminGet(req, res, next) { + try { + const user = await User.findById(req.params.userId) + .select('-password') + .lean() + .exec(); + + if (!user) return res.status(404).send('User not found'); + + user.maintainedTopics = await Topic.find({ maintainers: { $in: [user._id] } }); + + return res.json(user); + } catch (err) { + return next(err); + } +} + +async function update(req, res, next) { + try { + const fields = req.body; + const user = await User.findOneAndUpdate({ _id: req.params.userId }, fields, { new: true }) + .select('-password'); + + if (!user) return res.status(404).send('User not found'); + + return res.json(user.toObject()); + } catch (err) { + return next(err); + } +} + async function list(req, res, next) { try { - const { username, email, name } = req.query; + const find = searchParser.parse(req, { regexFields: ['name', 'email'] }); - const query = User.find(); - if (username) { - query.where('username').regex(new RegExp(username, 'i')); - } + const query = User.find(find); - if (email) { - query.where('email').regex(new RegExp(email, 'i')); - } + const users = await query + .limit(200) + .where('name').ne('Software Engineer') + .select('-password') + .exec(); + + const filtered = users.filter((user) => { + return !/(Software Developer-)/.test(user); + }); - if (name) { - query.where('name').regex(new RegExp(name, 'i')); - } + return res.json(filtered.slice(0, 150)); + } catch (err) { + return next(err); + } +} + +async function listNames(req, res, next) { + try { + const query = User.find(); const users = await query + .where('name').regex(new RegExp(req.query.name, 'i')) + .where('name').ne('Software Engineer') .limit(100) - .select('-password') + .select('name avatarUrl') .exec(); return res.json(users); @@ -283,6 +348,15 @@ function listBookmarked(req, res, next) { }); } +function removeBookmarked(req, res) { + const userId = req.userLoaded ? req.userLoaded._id : req.user._id; + + Favorite.findOne({ userId, postId: req.params.postId }) + .remove() + .then(() => res.end('Ok')) + .catch(err => res.status(400).end(err.message)); +} + function updateEmailNotiicationSettings(req, res, next) { const user = req.fullUser; user.emailNotiicationSettings = req.body; // eslint-disable-line no-param-reassign @@ -294,14 +368,30 @@ function updateEmailNotiicationSettings(req, res, next) { }); } +async function getTopics(req, res) { + const { userId } = req.params; + try { + const topics = await Topic.find({ maintainers: { $in: [userId] } }); + res.json(topics); + } catch (e) { + res.status(500).send(e.errmsg || e); + } +} + export default { load, + getAll, + update, + adminGet, get, me, list, - update, + listNames, + updateProfile, listBookmarked, + removeBookmarked, requestPasswordReset, updateEmailNotiicationSettings, - regainPassword + regainPassword, + getTopics }; diff --git a/server/controllers/vote.controller.js b/server/controllers/vote.controller.js index 1b9b074d..d6ea7657 100644 --- a/server/controllers/vote.controller.js +++ b/server/controllers/vote.controller.js @@ -1,6 +1,10 @@ import Bluebird from 'bluebird'; import Vote from '../models/vote.model'; +import Comment from '../models/comment.model'; +import { subscribePostFromEntity } from '../controllers/postSubscription.controller'; +import { subscribeTopicPage } from '../controllers/topicPageSubscription.controller'; +import { saveAndNotifyUser } from '../controllers/notification.controller'; /** * @swagger @@ -275,8 +279,63 @@ function downvote(req, res, next) { .catch(e => next(e)); } +async function subscribeAndNotify(vote, user) { + const comment = await Comment.findOne({ _id: vote.entityId }); + + if (!comment || (comment && user._id === comment.author)) { + return; + } + + let payload; + + if (!comment.entityType || comment.entityType === 'post') { + const post = await subscribePostFromEntity(comment.rootEntity, user); + + if (!post) return; + + payload = { + notification: { + title: `New upvote from @${user.name}`, + body: post.title.rendered, + data: { + user: user.username, + commentAuthor: comment.author, + thread: post.thread, + slug: post.slug + } + }, + type: 'upvote', + entity: post._id + }; + } + + if (comment.entityType === 'topic') { + const topic = await subscribeTopicPage(comment.rootEntity, user); + + if (!topic) return; + + payload = { + notification: { + title: `New upvote from @${user.name}`, + body: topic.name, + data: { + user: user.username, + url: `/topic/${topic.slug}`, + slug: topic.slug + } + }, + type: 'upvote', + entity: comment.rootEntity + }; + } + + // just notify the commenter + saveAndNotifyUser(payload, comment.author); +} + function finish(req, res) { req.vote = req.vote.toObject(); + if (req.vote.direction === 'upvote') subscribeAndNotify(req.vote, req.user); // Pass down the entity // We are getting the correct vote information to be part of the // entity object so that the clients can have an easier time figuring diff --git a/server/crons/rssFeed.cron.js b/server/crons/rssFeed.cron.js new file mode 100644 index 00000000..cf5c2ce7 --- /dev/null +++ b/server/crons/rssFeed.cron.js @@ -0,0 +1,175 @@ +import { toXML } from 'jstoxml'; +import { cloneDeep } from 'lodash'; +import moment from 'moment'; +import config from '../../config/config'; +import CronItem from '../helpers/cronItem.helper'; +import { getAdFreeMp3 } from '../helpers/mp3.helper'; +import app from '../../config/express'; +import Post from '../models/post.model'; + +const itunesImage = toXML({ + _name: 'itunes:image', + _attrs: { + href: 'https://www.softwaredaily.com/static/sedailywords.png' + } +}); + +const itunesCategory = toXML({ + _name: 'itunes:category', + _attrs: { + text: 'News' + }, + _content: { + _name: 'itunes:category', + _attrs: { + text: 'Tech News' + }, + } +}); + +// RSS header +const rawFeedConfig = { + _name: 'rss', + _attrs: { + version: '2.0', + 'xmlns:itunes': 'http://www.itunes.com/dtds/podcast-1.0.dtd', + 'xmlns:content': 'http://purl.org/rss/1.0/modules/content/' + }, + _content: { + channel: [ + { title: 'Software Daily' }, + { link: 'https://www.softwaredaily.com' }, + { language: 'en-us' }, + { copyright: '© SoftwareDaily.com' }, + { lastBuildDate: () => new Date() }, + { 'itunes:author': 'SoftwareDaily.com' }, + { description: 'Technical interviews about software topics.' }, + { 'itunes:type': 'serial' }, + { 'itunes:summary': 'Technical interviews about software topics.' }, + { 'itunes:explicit': 'no' }, + { + 'itunes:owner': { + 'itunes:name': 'Software Daily', + 'itunes:email': 'jeff@softwareengineeringdaily.com', + } + }, + itunesImage, + itunesCategory, + ] + } +}; + +function decode(text) { + return (text || '') + .replace(/&/g, '&') + .replace(/ /g, '') // Corrention + .replace(/amp;/g, '') // Correction in malformed links + .replace(/</g, '<') + .replace(/>/g, '>'); +} + +function encode(text) { + return (text || '') + .replace(/&/g, '&') + .replace(/amp;/g, '') // Correction in malformed links + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + +async function callback() { + const posts = await Post + .find() + .where('status') + .equals('publish') + .select('id mp3 adFreeMp3 title excerpt description mainImage link date_gmt') + .lean(); + + // mongoose sort is slower + posts.sort((o1, o2) => { + return o1.date >= o2.date ? -1 : 1; + }); + + const publicFeedAllConfig = cloneDeep(rawFeedConfig); + const publicFeedConfig = cloneDeep(rawFeedConfig); + const privateFeedConfig = cloneDeep(rawFeedConfig); + const lastPost = posts[posts.length - 1]; + + let episode = posts.length + 1; + const seasonYear = moment(lastPost.date_gmt).year(); + + posts.forEach((post) => { + episode -= 1; + + if (!post.mp3) return; // missing mp3 breaks the rss list + + let description; + + const extractedDescription = post.excerpt.rendered.match(/ Download (.*?)[<]/) || post.excerpt.rendered.match(/[>](.*?)[<]/); + + if (extractedDescription && extractedDescription.length && extractedDescription[1]) { + [, description] = extractedDescription; + description = decode(description); + } + + const item = [ + { + _name: 'enclosure', + _attrs: { + type: 'audio/mpeg', + url: post.mp3, + length: '1000' + }, + }, + { 'itunes:episodeType': 'full' }, + { 'itunes:episode': episode }, + { 'itunes:season': seasonYear - moment(post.date_gmt).year() }, + { title: encode(post.title.rendered) }, + { 'itunes:title': encode(post.title.rendered) }, + { description: `` }, + { + _name: 'itunes:image', + _attrs: { + href: encode(post.mainImage) + }, + }, + { link: encode(post.link) }, + { guid: parseInt(post.id, 10).toString(36) }, + { pubDate: moment.utc(post.date_gmt).format('ddd, DD MMM YYYY HH:mm:ss ZZ') }, + { 'itunes:explicit': 'no' }, + itunesCategory, + ]; + + // RSS item for each episode + publicFeedConfig._content.channel.push({ item }); + + const privateMp3 = post.adFreeMp3 || getAdFreeMp3(post.mp3); + const privateItem = cloneDeep(item); + + privateItem[0]._attrs.url = privateMp3; + privateFeedConfig._content.channel.push({ item: privateItem }); + }); + + publicFeedAllConfig._content.channel = publicFeedConfig._content.channel; + publicFeedConfig._content.channel = publicFeedConfig._content.channel.slice(0, 300); + + const xmlOptions = { + header: true, + indent: ' ' + }; + + app.set('rssFeedPublicAll', toXML(publicFeedAllConfig, xmlOptions)); + app.set('rssFeedPublic', toXML(publicFeedConfig, xmlOptions)); + app.set('rssFeedPrivate', toXML(privateFeedConfig, xmlOptions)); +} + +const rssFeed = { + name: 'rssFeed', + time: config.cron.RSS.time, + timeZone: config.cron.RSS.timeZone, + runOnInit: true, + callback, +}; + +export default new CronItem(rssFeed); diff --git a/server/helpers/activity.helper.js b/server/helpers/activity.helper.js new file mode 100644 index 00000000..1f075884 --- /dev/null +++ b/server/helpers/activity.helper.js @@ -0,0 +1,287 @@ +import moment from 'moment'; +import { groupBy } from 'lodash'; +import Comment from '../models/comment.model'; +import RelatedLink from '../models/relatedLink.model'; +import Post from '../models/post.model'; +import Answer from '../models/answer.model'; +import TopicPage from '../models/topicPage.model'; +import Topic from '../models/topic.model'; + +const cachedPosts = []; +const cachedTopicPages = []; +const cachedTopics = []; + +async function getActivityTree(userId, days) { + const limitDate = moment().subtract(days, 'days'); + const comments = await getComments(userId, limitDate); + + const postComments = comments.filter(c => !c.entityType || c.entityType === 'forumthread'); + const topicComments = comments.filter(c => c.entityType === 'topic'); + + await populatePosts({ + data: postComments, + field: 'rootEntity', + postField: 'thread', + cache: cachedPosts + }); + + await populateTopic({ + data: topicComments, + field: 'rootEntity', + type: 'topicPage', + cache: cachedTopicPages + }); + + const relatedLinks = await getRelatedLinks(userId, limitDate); + const answeredQuestions = await getAnsweredQuestions(userId, limitDate); + const postRelatedLinks = relatedLinks.filter(r => r.post); + const topicRelatedLinks = relatedLinks.filter(r => r.topicPage); + + await populatePosts({ + data: postRelatedLinks, + field: 'post', + postField: '_id', + cache: cachedPosts + }); + + await populateTopic({ + data: topicRelatedLinks, + field: 'topicPage', + type: 'topicPage', + cache: cachedTopicPages + }); + + const topicChanges = await getTopicChanges(userId); + + const activities = [].concat( + postComments, + topicComments, + answeredQuestions, + relatedLinks, + topicChanges + ); + + if (!activities.length) { + return null; + } + + activities.sort((o1, o2) => { + return o1.dateCreated >= o2.dateCreated ? -1 : 1; + }); + + return groupBy(activities, 'groupDate'); +} + +async function getTopicChanges(userId) { + const pages = await TopicPage.find({ 'history.user': userId }); + + await populateTopic({ + data: pages, + field: 'topic', + type: 'topic', + cache: cachedTopics + }); + + const activities = []; + + pages.forEach((page) => { + page.history.forEach((event) => { + if (event.user.toString() !== userId.toString()) return; + if (event.event === 'unpublish') return; + const eventDate = moment(event.dateCreated); + const groupDate = eventDate.format('YYYY-MM-DD'); + const activity = activities.find(a => a.groupDate === groupDate && a.event === event.event); + if (!activity) { // just one change per day + activities.push({ + dateCreated: eventDate.toDate(), + groupDate, + event: event.event, + activityType: event.event === 'edit' ? 'topicPageChange' : 'topicPagePublish', + entity: page.entity, + topic: page.topic + }); + } + }); + }); + + return activities; +} + +async function getComments(userId, limitDate) { + return Comment.find({ + author: userId, + dateCreated: { $gte: limitDate.toDate() }, + deleted: false, + }) + .select('rootEntity entityType dateCreated highlight content mentions') + .populate('mentions') + .sort('-dateCreated') + .lean() + .exec() + .map(async (item) => { + return { + ...item, + activityType: 'comment', + groupDate: moment(item.dateCreated).format('YYYY-MM-DD'), + }; + }); +} + +async function getAnsweredQuestions(userId, limitDate) { + const options = { + author: userId, + dateCreated: { + $gte: limitDate.toDate(), + }, + $or: [{ + deleted: false, + }, { + deleted: { + $exists: false, + }, + }], + }; + + let answers = await Answer.find(options) + .select('content dateCreated question') + .populate('question') + .sort('-dateCreated') + .lean() + .exec(); + + answers = answers.map(item => ({ + ...item, + topic: item.question.entityId, + activityType: 'answer', + groupDate: moment(item.dateCreated).format('YYYY-MM-DD'), + })); + + await populateTopic({ + data: answers, + field: 'topic', + type: 'topic', + cache: cachedTopics + }); + + return answers + .filter(a => a.entity) + .map(a => ({ + ...a, + entity: { + ...a.entity, + title: a.question.content, + url: `/${a.question.entityType}/${a.entity.slug}/question/${a.question._id}#answer-${a._id}`, + }, + })); +} + +async function getRelatedLinks(userId, limitDate) { + return RelatedLink.find({ + author: userId, + dateCreated: { $gte: limitDate.toDate() }, + deleted: false + }) + .select('post topicPage url dateCreated title type') + .sort('-dateCreated') + .lean() + .exec() + .map((item) => { + return { + ...item, + activityType: 'relatedLink', + groupDate: moment(item.dateCreated).format('YYYY-MM-DD'), + }; + }); +} + +// populates post info from a cached array of posts that +// exists for this request +async function populatePosts(options) { + for (let i = 0; i < options.data.length; i += 1) { + const item = options.data[i]; + const find = item[options.field]; + + if (!find) { + return options.data; + } + + let post = options.cache.find((p) => { + const field = p[options.postField || '_id']; + if (!field) return false; + return field.toString() === find.toString(); + }); + + if (!post) { + try { + post = await getPost(find); // eslint-disable-line no-await-in-loop + if (post) { + post = post.toObject(); + post.title = post.title.rendered; + post.url = `/post/${post._id}/${post.slug}`; + options.cache.push(post); + } + } catch (e) { + console.error(e); // eslint-disable-line + } + } + + item.entity = post; // eslint-disable-line no-param-reassign + } + return options.data; +} + +async function populateTopic(options) { + for (let i = 0; i < options.data.length; i += 1) { + const item = options.data[i]; + const find = item[options.field]; + + let topic = options.cache.find(p => ( + p._id.toString() === find.toString() + )); + + if (!topic) { + try { + topic = (options.type === 'topic') + ? await getTopic(find) // eslint-disable-line no-await-in-loop + : await getTopicPage(find); // eslint-disable-line no-await-in-loop + + if (topic) { + topic = topic.toObject(); + topic.title = topic.name; + topic.url = `/topic/${topic.slug}`; + options.cache.push(topic); + } + } catch (e) { + console.error(e); // eslint-disable-line + } + } + + item.entity = topic; // eslint-disable-line no-param-reassign + } + return options.data; +} + +async function getPost(id) { + return Post.findOne({ $or: [{ thread: id }, { _id: id }] }) + .select('slug title thread') + .exec(); +} + +async function getTopicPage(id) { + const topicPage = await TopicPage.findById(id) + .populate('topic') + .exec(); + + return topicPage.topic; +} + +async function getTopic(id) { + const topic = await Topic.findById(id) + .exec(); + + return topic; +} + +export default { + getActivityTree +}; diff --git a/server/helpers/badge.helper.js b/server/helpers/badge.helper.js new file mode 100644 index 00000000..3362186b --- /dev/null +++ b/server/helpers/badge.helper.js @@ -0,0 +1,129 @@ +import Comment from '../models/comment.model'; +import RelatedLink from '../models/relatedLink.model'; +import Topic from '../models/topic.model'; +import Answer from '../models/answer.model'; + +const getEpisodeCount = async (author) => { + const goalCount = 5; + const count = await RelatedLink + .find({ + type: 'episode', + deleted: false, + author, + }) + .count(); + + const percent = Math.min(count / goalCount, 1) * 100; + const completed = (percent === 100); + const label = completed + ? 'Added 5 Related Episodes' + : 'Add 5 Related Episodes'; + + return { + id: 'related-episode', + count, + label, + percent, + tooltip: 'Add related episodes to episode pages', + icon: completed ? 'fa-trophy' : 'fa-podcast', + completed, + }; +}; + +const getHighlightCount = async (author) => { + const goalCount = 5; + const count = await Comment + .find({ + highlight: { + $exists: true, + }, + deleted: false, + author, + }) + .count(); + + const percent = Math.min(count / goalCount, 1) * 100; + const completed = (percent === 100); + const label = completed + ? 'Added 5 Highlights' + : 'Add 5 Highlights'; + + return { + id: 'highlight', + count, + label, + percent, + tooltip: 'Highlight interesting parts of an episode', + icon: completed ? 'fa-trophy' : 'fa-quote-left', + completed, + }; +}; + +const getTopicCount = async (maintainer) => { + const goalCount = 1; + const count = await Topic + .find({ + status: 'active', + maintainer, + }) + .count(); + + const percent = Math.min(count / goalCount, 1) * 100; + const completed = (percent === 100); + const label = completed + ? 'Wrote 1 Topic Page' + : 'Write 1 Topic Page'; + + return { + id: 'topic', + count, + label, + percent, + tooltip: 'Write a topic page summarizing a topic', + icon: completed ? 'fa-trophy' : 'fa-pencil-square', + completed, + }; +}; + +const getAnswerCount = async (author) => { + const goalCount = 3; + const count = await Answer + .find({ + author, + }) + .count(); + + const percent = Math.min(count / goalCount, 1) * 100; + const completed = (percent === 100); + const label = completed + ? 'Answered 3 Questions' + : 'Answer 3 Questions'; + + return { + id: 'answer', + count, + label, + percent, + tooltip: 'Answer a question posted on a topic', + icon: completed ? 'fa-trophy' : 'fa-question', + completed, + }; +}; + +const getBadges = async (userId) => { + const episode = await getEpisodeCount(userId); + const highlight = await getHighlightCount(userId); + const topic = await getTopicCount(userId); + const answer = await getAnswerCount(userId); + + return [ + episode, + highlight, + topic, + answer, + ]; +}; + +export default { + getBadges, +}; diff --git a/server/helpers/cronItem.helper.js b/server/helpers/cronItem.helper.js new file mode 100644 index 00000000..6945f6c6 --- /dev/null +++ b/server/helpers/cronItem.helper.js @@ -0,0 +1,17 @@ +import { CronJob } from 'cron'; + +class CronItem { + constructor(config) { + this.name = config.name || ''; + this.time = config.time || null; + this.timeZone = config.timeZone; + this.runOnInit = config.runOnInit || false; + this.callback = config.callback; + } + + createJob() { + this.job = new CronJob(this.time, this.callback, null, false, this.timeZone || null, this); + } +} + +export default CronItem; diff --git a/server/helpers/forumNotifications.helper.js b/server/helpers/forumNotifications.helper.js deleted file mode 100644 index 486cef6e..00000000 --- a/server/helpers/forumNotifications.helper.js +++ /dev/null @@ -1,132 +0,0 @@ -import each from 'lodash/each'; -import sgMail from './mail'; -import config from '../../config/config'; -import Comment from '../models/comment.model'; -import ForumThread from '../models/forumThread.model'; - -function getUserDescription(userWhoReplied) { - let userDesc = 'Someone'; - if (userWhoReplied.username) { - userDesc = userWhoReplied.username; - } - if (userWhoReplied.name) { - userDesc = userWhoReplied.name; - } - return userDesc; -} - -// TODO: don't email if you are the author and replying to own stuff: -async function sendForumNotificationEmail({ threadId, content, userWhoReplied }) { - try { - const userIdWhoReplied = userWhoReplied._id; - const userDesc = getUserDescription(userWhoReplied); - const thread = await ForumThread.get(threadId); - const userToEmail = thread.author; - const { email, _id } = thread.author; - if (userToEmail.emailNotiicationSettings && - userToEmail.emailNotiicationSettings.unsubscribedFromThreads) return; - - // Don't email if you are the author and replying to own stuff: - if (userIdWhoReplied.toString() === _id.toString()) return; - const contentSummary = content.substr(0, 50); - const msg = { - to: email, - from: 'no-reply@softwaredaily.com', - subject: 'Someone commented on your thread @SoftwareDaily', - text: `${userDesc} commented in your thread: ${config.baseUrl}/forum/${threadId}`, - html: `${userDesc} commented on your post. -
-
- "${contentSummary}..." - [ click to read more] -

Unsubscribe ` - }; - sgMail.send(msg); - } catch (e) { - console.log('Error emailing notification', e); - } -} - -async function sendReplyNotificationEmail({ - parentCommentId, content, threadId, userWhoReplied -}) { - // We need to get the info for the person who made the original comment: - try { - const userIdWhoReplied = userWhoReplied._id; - const userDesc = getUserDescription(userWhoReplied); - const parentComment = await Comment.get(parentCommentId); - const userToEmail = parentComment.author; - const { email, _id } = parentComment.author; - if (userToEmail.emailNotiicationSettings && - userToEmail.emailNotiicationSettings.unsubscribedFromCommentReplies) return; - - // Don't send if parentComment is owned by thread creator. To prevent - // double emailing. Make sure thread notifications are turned on: - if (userToEmail.emailNotiicationSettings && - !userToEmail.emailNotiicationSettings.unsubscribedFromThreads) { - const thread = await ForumThread.get(threadId); - if (thread.author._id.toString() === _id.toString()) return; - } - - // Don't email if you are the author and replying to own stuff: - if (userIdWhoReplied.toString() === _id.toString()) return; - - const contentSummary = content.substr(0, 50); - const msg = { - to: email, - from: 'no-reply@softwaredaily.com', - subject: 'Someone replied to you in the SoftwareDaily Forum', - text: `${userDesc} replied to your comment: ${config.baseUrl}/forum/${threadId}`, - html: `${userDesc} replied to your comment. -
-
- "${contentSummary}..." - [ click to read more] -

Unsubscribe ` - }; - sgMail.send(msg); - } catch (e) { - console.log('Error emailing notification:', e); - } -} - - -async function sendMentionsNotificationEmail({ - content, threadId, userWhoReplied, usersMentioned -}) { - try { - const userDesc = getUserDescription(userWhoReplied); - - const contentSummary = content.substr(0, 50); - each(usersMentioned, (userToEmail) => { - if (userToEmail.emailNotiicationSettings && - userToEmail.emailNotiicationSettings.unsubscribedFromMentions) { - console.log('Unsubscribed from mentions', userToEmail); - } else { - const { email } = userToEmail; - const msg = { - to: email, - from: 'no-reply@softwaredaily.com', - subject: 'Someone mentioned you in a thread @SoftwareDaily', - text: `${userDesc} mentioned you: ${config.baseUrl}/forum/${threadId}`, - html: `${userDesc} mentioned you. -
-
- "${contentSummary}..." - [ click to read more] -

Unsubscribe ` - }; - sgMail.send(msg); - } - }); - } catch (e) { - console.log('Error emailing notification', e); - } -} - - -export default { - sendForumNotificationEmail, - sendMentionsNotificationEmail, - sendReplyNotificationEmail -}; diff --git a/server/helpers/job.helper.js b/server/helpers/job.helper.js index fe06ad10..58cc8729 100644 --- a/server/helpers/job.helper.js +++ b/server/helpers/job.helper.js @@ -7,6 +7,7 @@ const fieldsForAuthor = [ 'location', 'title', 'description', + 'topics', 'tags', 'employmentType', 'remoteWorkingConsidered', @@ -22,6 +23,7 @@ const fieldsForReader = [ 'location', 'title', 'description', + 'topics', 'tags', 'employmentType', 'remoteWorkingConsidered', diff --git a/server/helpers/mail.js b/server/helpers/mail.js index 49b8bd38..16202f61 100644 --- a/server/helpers/mail.js +++ b/server/helpers/mail.js @@ -1,7 +1,61 @@ import config from '../../config/config'; +import MailTemplate from '../controllers/mailTemplate.controller'; const sgMail = require('@sendgrid/mail'); sgMail.setApiKey(config.sendGridKey); -export default sgMail; +const options = { + templatesFiles: [ + 'sd-simple-template', + 'sd-template-comment' + ], + + bodiesFiles: [ + 'sd-simple-body', + 'sd-body-topic-maintainer', + 'sd-body-topic-publish', + 'sd-body-topic-new-question', + 'sd-body-topic-new-answer', + 'sd-body-topic-new-maintainer', + 'sd-body-post-comment-author', + 'sd-body-post-comment-reply', + 'sd-body-post-comment-mention' + ], + + mailTemplates: [{ + name: 'simple', + body: 'sd-simple-body' + }, { + name: 'topicMaintainer', + body: 'sd-body-topic-maintainer' + }, { + name: 'topicPublish', + body: 'sd-body-topic-publish' + }, { + name: 'topicNewMaintainer', + body: 'sd-body-topic-new-maintainer' + }, { + name: 'topicQuestion', + body: 'sd-body-topic-new-question' + }, { + name: 'topicAnswer', + body: 'sd-body-topic-new-answer' + }, { + name: 'postNewCommentAuthor', + body: 'sd-body-post-comment-author' + }, { + name: 'postNewCommentReply', + body: 'sd-body-post-comment-reply' + }, { + name: 'postNewCommentMention', + body: 'sd-body-post-comment-mention' + }] +}; + +const mailTemplate = new MailTemplate(options, sgMail); + +export default { + sgMail, + mailTemplate +}; diff --git a/server/helpers/mailNotification.helper.js b/server/helpers/mailNotification.helper.js new file mode 100644 index 00000000..8e64ab25 --- /dev/null +++ b/server/helpers/mailNotification.helper.js @@ -0,0 +1,199 @@ + +import config from '../../config/config'; +import Comment from '../models/comment.model'; +import Post from '../models/post.model'; +import TopicPage from '../models/topicPage.model'; +import User from '../models/user.model'; +import { mailTemplate } from '../helpers/mail'; + +async function handleNotification(entityId, entityType, user, rawComment) { + const { comment, commenter, entityData } = await getData(entityId, entityType, user, rawComment); + + // always send to entity author + if (isSubscribed(entityData.author, 'thread')) mailThreadAuthor(entityData, commenter, comment); + + // send to comment author when is a reply + if (comment.parentComment && isSubscribed(comment.parentComment.author, 'reply')) { + mailReply(entityData, commenter, comment); + } + + // send for mentioned + if (comment.mentionedUsers && comment.mentionedUsers.length) { + comment.mentionedUsers.forEach((mentionedUser) => { + if (isSubscribed(mentionedUser, 'mention')) mailMention(entityData, commenter, comment, mentionedUser); + }); + } +} + +async function handleUpdatedComment(entityId, entityType, user, rawComment, newMentions) { + const { comment, commenter, entityData } = await getData(entityId, entityType, user, rawComment); + + if (newMentions && newMentions.length) { + newMentions.forEach((mentionedUser) => { + if (isSubscribed(mentionedUser, 'mention')) mailMention(entityData, commenter, comment, mentionedUser); + }); + } +} + +async function getData(entityId, entityType, user, rawComment) { + const comment = rawComment.toObject(); + await setMentionContent(comment); + comment.content = comment.content.replace(/\n/g, '
'); + + const entityData = await getEntityData(entityId, entityType); + if (!entityData) return {}; + + const commenter = { + ...user, + fullName: user.lastName ? `${user.name} ${user.lastName}` : user.name + }; + if (comment.parentComment) { + comment.parentComment = await Comment.findById(comment.parentComment).populate('author', '-password').lean(); + if (comment.parentComment.author) { + comment.parentComment.content = comment.parentComment.content.replace(/\n/g, '
'); + await setMentionContent(comment.parentComment); + const pa = comment.parentComment.author; + comment.parentComment.author.fullName = pa.lastName ? `${pa.name} ${pa.lastName}` : pa.name; + } + } + + return { comment, commenter, entityData }; +} + +function mailThreadAuthor(entityData, commenter, comment) { + if (!entityData.author.email) return; + if (commenter._id.toString() === entityData.author._id.toString()) return; + + mailTemplate.postNewCommentAuthor({ + to: entityData.author.email, + subject: `New comment on ${entityData.title}`, + data: { + user: entityData.author.fullName, + commenter, + comment, + entityLink: entityData.link, + entityName: entityData.name, + unsubscribeLink: `${config.baseUrl}/settings` + } + }); +} + +function mailReply(entityData, commenter, comment) { + if (!comment.parentComment.author || !comment.parentComment.author.email) return; + if (commenter._id.toString() === comment.parentComment.author._id.toString()) return; + + mailTemplate.postNewCommentReply({ + to: comment.parentComment.author.email, + subject: `New replied comment on ${entityData.title}`, + data: { + user: comment.parentComment.author.fullName, + commenter, + comment, + entityLink: entityData.link, + entityName: entityData.name, + unsubscribeLink: `${config.baseUrl}/settings` + } + }); +} + +function mailMention(entityData, commenter, comment, mentionedUser) { + if (!mentionedUser || !mentionedUser.email) return; + if (commenter._id.toString() === mentionedUser._id.toString()) return; + + mailTemplate.postNewCommentMention({ + to: mentionedUser.email, + subject: `New mention on ${entityData.title}`, + data: { + user: mentionedUser.fullName, + commenter, + comment, + entityLink: entityData.link, + entityName: entityData.name, + unsubscribeLink: `${config.baseUrl}/settings` + } + }); +} + +async function getEntityData(entityId, entityType) { + if (entityType === 'forumthread') { + const post = await Post.findOne({ thread: entityId }) + .populate('thread') + .lean(); + + const author = await User.findById(post.thread.author).select('name lastName emailNotificationSettings email').lean(); + if (!author) return false; + author.fullName = author.lastName ? `${author.name} ${author.lastName}` : author.name; + + return { + entity: post, + name: 'post', + title: post.title.rendered, + link: `${config.baseUrl}/post/${post._id}/${post.slug}`, + author + }; + } + + if (entityType === 'topic') { + const topicPage = await TopicPage.findById(entityId) + .populate('topic') + .lean() + .exec(); + + const author = await User.findById(topicPage.topic.maintainer).select('name lastName emailNotificationSettings email').lean(); + if (!author) return false; + author.fullName = author.lastName ? `${author.name} ${author.lastName}` : author.name; + + return { + entity: topicPage, + name: 'topic', + title: topicPage.topic.name, + link: `${config.baseUrl}/topic/${topicPage.topic.slug}`, + author + }; + } + + return null; +} + +function isSubscribed(user, type) { + if (!user.emailNotificationSettings) return true; + + switch (type) { + case 'thread': return !user.emailNotificationSettings.unsubscribedFromThreads; + case 'reply': return !user.emailNotificationSettings.unsubscribedFromCommentReplies; + case 'mention': return !user.emailNotificationSettings.unsubscribedFromThreads; + default: + return false; + } +} + +async function getMentionedUsers(mentions) { + const users = []; + + for (let i = 0; i < mentions.length; i += 1) { + const user = await User.findById(mentions[i]) // eslint-disable-line + .select('name lastName email avatarUrl emailNotificationSettings') + .lean(); + if (user && !users.find(u => u._id === user._id)) { + user.fullName = user.lastName ? `${user.name} ${user.lastName}` : user.name; + users.push(user); + } + } + + return users; +} + +async function setMentionContent(comment) { + if (!comment.mentions || !comment.mentions.length) return; + + comment.mentionedUsers = await getMentionedUsers(comment.mentions); // eslint-disable-line + + comment.mentionedUsers.forEach((user) => { + comment.content = comment.content.replace(new RegExp(`@${user._id}`, 'ig'), `@${user.fullName}`); // eslint-disable-line + }); +} + +export default { + handleNotification, + handleUpdatedComment +}; diff --git a/server/helpers/mp3.helper.js b/server/helpers/mp3.helper.js new file mode 100644 index 00000000..ff110944 --- /dev/null +++ b/server/helpers/mp3.helper.js @@ -0,0 +1,17 @@ +const privateMp3URL = 'https://s3-us-west-2.amazonaws.com/sd-profile-pictures/adfree/'; + +function getAdFreeMp3(originalMp3) { + if (typeof originalMp3 !== 'string') return originalMp3; + + const extractedFile = originalMp3.toString().match(/\/traffic.libsyn.co.+\/sedaily\/(.*?).mp3/); + + let privateMp3 = originalMp3; + + if (extractedFile && extractedFile.length && extractedFile[1]) { + privateMp3 = `${privateMp3URL}${extractedFile[1]}_adfree.mp3`; + } + + return privateMp3; +} + +export default { getAdFreeMp3 }; diff --git a/server/helpers/post.helper.js b/server/helpers/post.helper.js index 35055f13..aced12c3 100644 --- a/server/helpers/post.helper.js +++ b/server/helpers/post.helper.js @@ -1,34 +1,96 @@ -import config from '../../config/config'; - -function replaceWithAdFree(post) { - try { - const originalMP3Split = post.mp3.split('/'); - if (originalMP3Split.length > 0) { - const fileName = originalMP3Split[originalMP3Split.length - 1]; - const newFileName = fileName.replace('.mp3', '_adfree.mp3'); - post.mp3 = config.adFreeURL + newFileName; // eslint-disable-line - } - } catch (e) { - console.log('Error, could not get mp3', post, e); // eslint-disable-line - // next(e); // We don't want to do this since it could still return posts. +import algoliasearch from 'algoliasearch'; +import Vote from '../models/vote.model'; +import Favorite from '../models/favorite.model'; +import { getAdFreeMp3 } from '../helpers/mp3.helper'; +import { getPrivateRss } from '../helpers/rss.helper'; + +function replaceWithAdFree(post, fullUser) { + post.mp3 = post.adFreeMp3 || getAdFreeMp3(post.mp3) // eslint-disable-line + post.rss = getPrivateRss(fullUser) // eslint-disable-line +} + +async function getSearchQuery({ + search, topic, limit, createdAtBefore +}) { + const client = algoliasearch( + process.env.ALGOLIA_APP_ID, + process.env.ALGOLIA_API_KEY, + ); + + const index = client.initIndex(process.env.ALGOLIA_POSTS_INDEX); + const timestamp = createdAtBefore ? new Date(createdAtBefore).getTime() : new Date().getTime(); + const searchQuery = { + query: search, + filters: `date_timestamp < ${timestamp}`, + hitsPerPage: limit || 10, + }; + + if (topic) { + searchQuery.filters += ` AND topics:${topic}`; } - return post; + + return new Promise((resolve, reject) => { + index.search(searchQuery) + .then((reply) => { + return resolve({ + slug: { + $in: reply.hits.map(h => h.slug), + }, + }); + }) + .catch(e => reject(e)); + }); } -function getAdFreeSinglePostIfSubscribed(post, fullUser, next) { +async function addPostData(post, fullUser) { + const query = { + userId: fullUser ? fullUser._id : null, + postId: post._id, + active: true, + }; + + const upvoted = await Vote + .findOne(query) + .exec(l => Promise.resolve(l)); + + const bookmark = await Favorite + .findOne(query) + .exec(l => Promise.resolve(l)); + + post.upvoted = !!(upvoted) // eslint-disable-line + post.totalFavorites = post.totalFavorites || 0 // eslint-disable-line + post.bookmarked = !!(bookmark && bookmark.active) // eslint-disable-line + post.rss = '/rss/public/all' // eslint-disable-line + if (fullUser && fullUser.subscription && fullUser.subscription.active) { - return replaceWithAdFree(post, next); + replaceWithAdFree(post, fullUser); + } else { + post.adFreeMp3 = null; // eslint-disable-line } + return post; } -function getAdFreePostsIfSubscribed(posts, fullUser, next) { - if (fullUser && fullUser.subscription && fullUser.subscription.active) { - // Here we do this so we can fetch subscritions: - const _posts = posts.map(post => replaceWithAdFree(post, next)); - return _posts; +async function getAdFreePostsIfSubscribed(posts, fullUser) { + if (!fullUser) { + return posts; } - return posts; + + // Here we do this so we can + // fetch subscriptions: + const _posts = posts.map(async (post) => { + return await addPostData( // eslint-disable-line + typeof post.toObject === 'function' ? post.toObject() : post, + fullUser, + ); + }); + + return Promise.all(_posts); } -export { replaceWithAdFree, getAdFreeSinglePostIfSubscribed, getAdFreePostsIfSubscribed }; +export { + getSearchQuery, + replaceWithAdFree, + addPostData, + getAdFreePostsIfSubscribed, +}; diff --git a/server/helpers/rss.helper.js b/server/helpers/rss.helper.js new file mode 100644 index 00000000..f7ebc8c8 --- /dev/null +++ b/server/helpers/rss.helper.js @@ -0,0 +1,9 @@ +function getPrivateRss(user) { + if (!user || !user.subscription || !user.subscription.active) return '/rss/public/all'; + const rssPrivateCode = Buffer.from(user.subscription._id.toString(), 'utf8').toString('base64'); + return `/rss/private/${rssPrivateCode}`; +} + +export default { + getPrivateRss +}; diff --git a/server/helpers/searchParser.helper.js b/server/helpers/searchParser.helper.js new file mode 100644 index 00000000..d0aac8a4 --- /dev/null +++ b/server/helpers/searchParser.helper.js @@ -0,0 +1,33 @@ + +import qs from 'qs-mongodb'; + +function replaceRegex(item, regexFields) { + Object.keys(item).forEach((key) => { + if (Array.isArray(item[key])) { + item[key].forEach((arrItem) => { + replaceRegex(arrItem, regexFields); + }); + } + if (typeof item[key] === 'string' && regexFields.includes(key)) { + item[key] = { $regex: item[key], $options: 'i' }; // eslint-disable-line + } + return item; + }); + return item; +} + +function parse(req, options = {}) { + if (!req._parsedUrl) return undefined; + + const query = qs.parse(req._parsedUrl.query); + + if (options.regexFields) { + replaceRegex(query, options.regexFields); + } + + return query; +} + +export default { + parse +}; diff --git a/server/middleware/ensureIsSuperAdmin.middleware.js b/server/middleware/ensureIsSuperAdmin.middleware.js new file mode 100644 index 00000000..3a9fb663 --- /dev/null +++ b/server/middleware/ensureIsSuperAdmin.middleware.js @@ -0,0 +1,14 @@ +import httpStatus from 'http-status'; +import APIError from '../helpers/APIError'; + +export default // NOTE requires full user to be called.. +// eslint-disable-next-line +async function ensureIsSuperAdmin(req, res, next) { + const loggedInUser = req.fullUser.toObject(); + if (!loggedInUser.isSuperAdmin) { + let err = new APIError('Must be an Super Admin to do that', httpStatus.UNAUTHORIZED, true); //eslint-disable-line + return next(err); + } + req.isSuperAdmin = true; + next(); +} diff --git a/server/middleware/response.middleware.js b/server/middleware/response.middleware.js new file mode 100644 index 00000000..992dd009 --- /dev/null +++ b/server/middleware/response.middleware.js @@ -0,0 +1,3 @@ +export default function response(req, res) { + res.json(req.response || {}); +} diff --git a/server/middleware/validateRecaptcha.middleware.js b/server/middleware/validateRecaptcha.middleware.js new file mode 100644 index 00000000..eccaba55 --- /dev/null +++ b/server/middleware/validateRecaptcha.middleware.js @@ -0,0 +1,21 @@ +import httpStatus from 'http-status'; +import ReCAPTCHA from 'recaptcha2'; +import config from '../../config/config'; +import APIError from '../helpers/APIError'; + +const reCaptcha = new ReCAPTCHA({ + siteKey: config.recaptcha.siteKey, + secretKey: config.recaptcha.secretKey +}); + +function validateRecaptcha(req, res, next) { + const { recaptchaResponse } = req.body; + return reCaptcha.validate(recaptchaResponse) + .then(() => next()) + .catch((errorCodes) => { + const error = new APIError(`Recaptcha error: ${reCaptcha.translateErrors(errorCodes)}`, httpStatus.UNAUTHORIZED, true); + return next(error); + }); +} + +export default validateRecaptcha; diff --git a/server/models/answer.model.js b/server/models/answer.model.js new file mode 100644 index 00000000..e4941765 --- /dev/null +++ b/server/models/answer.model.js @@ -0,0 +1,16 @@ +import mongoose from 'mongoose'; +import config from '../../config/config'; + +// Create schema +const AnswerSchema = new mongoose.Schema({ + question: { type: mongoose.Schema.Types.ObjectId, ref: 'Question' }, + content: { type: String }, + author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + votes: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], + dateCreated: { type: Date, default: Date.now }, + dateUpdated: { type: Date, default: Date.now }, + deleted: { type: Boolean, default: false }, +}); + +// Export the model +module.exports = mongoose.model(`${config.mongo.collectionPrefix}Answer`, AnswerSchema); diff --git a/server/models/comment.model.js b/server/models/comment.model.js index ec99a6c9..89bdc40f 100644 --- a/server/models/comment.model.js +++ b/server/models/comment.model.js @@ -5,6 +5,7 @@ import mongoose, { Schema } from 'mongoose'; import httpStatus from 'http-status'; import APIError from '../helpers/APIError'; import Vote from './vote.model'; +import config from '../../config/config'; /** * @swagger * definitions: @@ -41,16 +42,21 @@ const CommentSchema = new Schema({ id: String, content: { type: String, - required: true }, - score: { type: Number, default: 0 }, + highlight: { + type: String, + }, + score: { + type: Number, + default: 0, + }, dateCreated: { type: Date, default: Date.now }, parentComment: { type: Schema.Types.ObjectId, - ref: 'Comment' + ref: 'Comment', }, deleted: { type: Boolean, @@ -64,6 +70,9 @@ const CommentSchema = new Schema({ type: Schema.Types.ObjectId // The entity that owns this comment // , ref: 'Post' | 'AMA' }, + entityType: { + type: String + }, mentions: [{ type: Schema.Types.ObjectId, ref: 'User' @@ -174,6 +183,10 @@ CommentSchema.statics = { }, getTopLevelCommentsForItem(entityId) { + if (!mongoose.Types.ObjectId.isValid(entityId)) { + return Promise.resolve([]); + } + return this.find({ rootEntity: entityId, parentComment: null }) .sort({ dateCreated: -1 }) .populate('mentions') @@ -227,4 +240,4 @@ CommentSchema.statics = { // Indexes CommentSchema.index({ content: 'text' }); -export default mongoose.model('Comment', CommentSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Comment`, CommentSchema); diff --git a/server/models/company.model.js b/server/models/company.model.js index 95b6f817..36b3e22e 100644 --- a/server/models/company.model.js +++ b/server/models/company.model.js @@ -1,5 +1,5 @@ - import mongoose, { Schema } from 'mongoose'; +import config from '../../config/config'; const CompanySchema = new mongoose.Schema({ companyName: { @@ -46,4 +46,4 @@ const CompanySchema = new mongoose.Schema({ } }); -export default mongoose.model('Company', CompanySchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Company`, CompanySchema); diff --git a/server/models/favorite.model.js b/server/models/favorite.model.js index 6b8489af..096831af 100644 --- a/server/models/favorite.model.js +++ b/server/models/favorite.model.js @@ -3,6 +3,7 @@ import mongoose from 'mongoose'; import httpStatus from 'http-status'; import APIError from '../helpers/APIError'; import Post from './post.model'; +import config from '../../config/config'; /** * todo: once clients migrated "bookmark" - do final refactor of code and db migration @@ -107,4 +108,4 @@ FavoriteSchema.statics = { } }; -export default mongoose.model('Favorite', FavoriteSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Favorite`, FavoriteSchema); diff --git a/server/models/feed.model.js b/server/models/feed.model.js index 353aac79..a9f78f96 100644 --- a/server/models/feed.model.js +++ b/server/models/feed.model.js @@ -1,4 +1,5 @@ import mongoose, { Schema } from 'mongoose'; +import config from '../../config/config'; const feedItemSchema = new Schema(); // TODO: replace with proper import const FeedSchema = new Schema({ @@ -9,4 +10,4 @@ const FeedSchema = new Schema({ feedItems: [feedItemSchema] }); -export default mongoose.model('Feed', FeedSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Feed`, FeedSchema); diff --git a/server/models/feedItem.model.js b/server/models/feedItem.model.js index 9d8d518a..9ca1dae0 100644 --- a/server/models/feedItem.model.js +++ b/server/models/feedItem.model.js @@ -1,5 +1,6 @@ import mongoose, { Schema } from 'mongoose'; import Vote from './vote.model'; +import config from '../../config/config'; const FeedItemSchema = new Schema({ user: { @@ -47,7 +48,7 @@ FeedItemSchema.statics = { }, addVotesForUserToEntities(items, userId) { - const ids = items.map((item) => { //eslint-disable-line + const ids = items.map((item) => { return item.relatedLink._id; }); return Vote.find({ @@ -79,7 +80,7 @@ FeedItemSchema.statics = { }; -export default mongoose.model('FeedItem', FeedItemSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}FeedItem`, FeedItemSchema); // Can have the frontend interweave the form posts .. nope.catch(( diff --git a/server/models/forumThread.model.js b/server/models/forumThread.model.js index 20327736..c897ea02 100644 --- a/server/models/forumThread.model.js +++ b/server/models/forumThread.model.js @@ -3,6 +3,7 @@ import moment from 'moment'; import httpStatus from 'http-status'; import APIError from '../helpers/APIError'; import Vote from './vote.model'; +import config from '../../config/config'; const ForumThreadSchema = new mongoose.Schema({ id: String, @@ -54,10 +55,11 @@ ForumThreadSchema.statics = { }); }, - increaseCommentCount(id) { + increaseCommentCount(id, count = 1) { return this.get(id).then((thread) => { const forumThread = thread; - forumThread.commentsCount += 1; + forumThread.commentsCount += count; + forumThread.commentsCount = Math.max(forumThread.commentsCount, 0); forumThread.dateLastAcitiy = new Date(); return forumThread.save(); }); @@ -92,7 +94,7 @@ ForumThreadSchema.statics = { }, addVotesForUserToEntities(entities, userId) { - const ids = entities.map((entity) => { //eslint-disable-line + const ids = entities.map((entity) => { return entity._id; }); return Vote.find({ @@ -131,4 +133,4 @@ ForumThreadSchema.statics = { */ }; -export default mongoose.model('ForumThread', ForumThreadSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}ForumThread`, ForumThreadSchema); diff --git a/server/models/job.model.js b/server/models/job.model.js index 01596ff1..24582891 100644 --- a/server/models/job.model.js +++ b/server/models/job.model.js @@ -1,4 +1,5 @@ import mongoose, { Schema } from 'mongoose'; +import config from '../../config/config'; /** * @swagger @@ -88,6 +89,9 @@ const JobSchema = new mongoose.Schema({ tags: [{ type: Number }], + topics: [{ + type: mongoose.Schema.Types.ObjectId, ref: 'Topic' + }], employmentType: { type: String, required: true, @@ -114,4 +118,4 @@ const JobSchema = new mongoose.Schema({ } }); -export default mongoose.model('Job', JobSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Job`, JobSchema); diff --git a/server/models/like.model.js b/server/models/like.model.js new file mode 100644 index 00000000..24c9b2b9 --- /dev/null +++ b/server/models/like.model.js @@ -0,0 +1,84 @@ +import mongoose from 'mongoose'; +import httpStatus from 'http-status'; +import APIError from '../helpers/APIError'; +import config from '../../config/config'; + +/** + * @swagger + * definitions: + * Like: + * type: object + * properties: + * _id: + * $ref '#/definitions/ObjectId' + * __v: + * $ref: '#/definitions/MongoVersion' + * userId: + * $ref '#/definitions/ObjectId' + * postId: + * $ref '#/definitions/ObjectId' + * dateCreated: + * type: string + * format: date-time + * description: Date comment created + * example: 2017-10-30T01:05:39.674Z + */ +const LikeSchema = new mongoose.Schema({ + userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + postId: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' }, + dateCreated: { type: Date, default: Date.now }, +}); + +/** + * Add your + * - pre-save hooks + * - validations + * - virtuals + */ + +/** + * Methods + */ +LikeSchema.method({}); + +/** + * Statics + */ +LikeSchema.statics = { + + /** + * Get like + * @param {ObjectId} id - The objectId of like. + * @returns {Promise} + */ + get(id, userId) { + return this.findOne({ _id: id, userId }) + .exec() + .then((like) => { + if (like) { + return like; + } + const err = new APIError('No such like exists!', httpStatus.NOT_FOUND); + return Promise.reject(err); + }); + }, + + /** + * List likes in descending order of 'createdAt' timestamp. + * @param {number} skip - Number of likes to be skipped. + * @param {number} limit - Limit number of likes to be returned. + * @returns {Promise} + */ + list({ skip = 0, limit = 50 } = {}, userId) { + return this.find({ userId }) + .sort({ createdAt: -1 }) + .skip(+skip) + .limit(+limit) + .exec(); + } +}; + +/** + * @typedef Like + */ +export default mongoose.model(`${config.mongo.collectionPrefix}Like`, LikeSchema); diff --git a/server/models/listened.model.js b/server/models/listened.model.js index c0832281..5b8ec562 100644 --- a/server/models/listened.model.js +++ b/server/models/listened.model.js @@ -2,6 +2,7 @@ import Promise from 'bluebird'; import mongoose from 'mongoose'; import httpStatus from 'http-status'; import APIError from '../helpers/APIError'; +import config from '../../config/config'; /** * @swagger @@ -100,4 +101,4 @@ ListenedSchema.statics = { } }; -export default mongoose.model('Listened', ListenedSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Listened`, ListenedSchema); diff --git a/server/models/notification.model.js b/server/models/notification.model.js new file mode 100644 index 00000000..abb07fbd --- /dev/null +++ b/server/models/notification.model.js @@ -0,0 +1,34 @@ +import mongoose, { Schema } from 'mongoose'; +import config from '../../config/config'; + +/** + * Schema + */ +const notificationSchema = new mongoose.Schema({ + to: { + type: Schema.Types.ObjectId, + ref: 'User' + }, + notification: { + type: Object + }, + type: { + type: String + }, + url: { + type: String + }, + entity: { + type: String + }, + read: { + type: Boolean, + default: false + }, + dateCreated: { + type: Date, + default: Date.now + } +}); + +export default mongoose.model(`${config.mongo.collectionPrefix}Notification`, notificationSchema); diff --git a/server/models/passport.model.js b/server/models/passport.model.js new file mode 100644 index 00000000..2f2a9369 --- /dev/null +++ b/server/models/passport.model.js @@ -0,0 +1,16 @@ +import mongoose, { Schema } from 'mongoose'; +import config from '../../config/config'; + +/** + * Passport Schema + */ +const PassportSchema = new Schema({ + expired: { type: Number, default: 0 }, + accessToken: { type: String }, + provider: { type: String, default: 'twitter' }, + identifier: { type: String, unique: true }, + tokens: { type: Object }, + user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, +}); + +export default mongoose.model(`${config.mongo.collectionPrefix}Passport`, PassportSchema); diff --git a/server/models/passwordReset.model.js b/server/models/passwordReset.model.js index d6f3027f..ae046e3f 100644 --- a/server/models/passwordReset.model.js +++ b/server/models/passwordReset.model.js @@ -1,4 +1,5 @@ import mongoose from 'mongoose'; +import config from '../../config/config'; const PasswordResetSchema = new mongoose.Schema({ userId: { @@ -34,4 +35,4 @@ PasswordResetSchema.statics = { } }; -export default mongoose.model('PasswordReset', PasswordResetSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}PasswordReset`, PasswordResetSchema); diff --git a/server/models/post.model.js b/server/models/post.model.js index 05c42654..ddf417b3 100644 --- a/server/models/post.model.js +++ b/server/models/post.model.js @@ -4,6 +4,12 @@ import moment from 'moment'; import httpStatus from 'http-status'; import APIError from '../helpers/APIError'; import Vote from './vote.model'; +import { getSearchQuery } from './../helpers/post.helper'; +import config from '../../config/config'; + +const slug = require('mongoose-slug-generator'); + +mongoose.plugin(slug); /** * @swagger @@ -38,6 +44,10 @@ import Vote from './vote.model'; * type: integer * description: Number of upvotes given to episode by logged in users * example: 3 + * likeCount: + * type: integer + * description: Number of likes given to post by logged in users + * example: 5 * upvote: * type: boolean * description: if authenticated, returns if user upvoted episode @@ -59,6 +69,7 @@ const PostSchema = new mongoose.Schema({ id: String, score: { type: Number, default: 0 }, totalFavorites: { type: Number, default: 0 }, + likeCount: { type: Number, default: 0 }, title: { rendered: String, }, @@ -69,7 +80,17 @@ const PostSchema = new mongoose.Schema({ content: { rendered: String, }, - date: { type: Date, default: Date.now } + description: { type: String }, + relatedTweet: { type: String }, + relatedTweetUsers: { type: Array }, + relatedPosts: [{ + type: mongoose.Schema.Types.ObjectId, + ref: 'Post' + }], + date: { type: Date, default: Date.now }, + transcriptUrl: { type: String, default: '' }, + topics: Array, + slug: { type: String, slug: 'name', unique: true }, }); /** @@ -78,7 +99,6 @@ const PostSchema = new mongoose.Schema({ * - validations * - virtuals */ - PostSchema.virtual('bookmarkedByUser', { ref: 'Favorite', localField: '_id', @@ -113,8 +133,32 @@ PostSchema.statics = { return Promise.reject(err); }); }, - // standard list of fields to select for find Post queries - standardSelectForFind: 'content title date mp3 link score featuredImage upvoted downvoted tags categories thread', + + /** + * Standard list of fields to select for find Post queries + */ + standardSelectForFind: [ + 'content', + 'totalFavorites', + 'title', + 'date', + 'mp3', + 'adFreeMp3', + 'link', + 'score', + 'slug', + 'featuredImage', + 'guestImage', + 'upvoted', + 'downvoted', + 'tags', + 'categories', + 'thread', + 'excerpt', + 'transcriptUrl', + 'topics', + ].join(' '), + /** * List posts in descending order of 'createdAt' timestamp. * @param {number} limit - Limit number of posts to be returned. @@ -123,9 +167,11 @@ PostSchema.statics = { * @param {list} tags - List of Tags Ids * @param {list} categories - List of Categories * @param {string} search - Post Title to search + * @param {string} transcripts - Get posts with or without transcripts * @returns {Promise} */ - list({ + async list({ + slugs = [], limit = 10, createdAtBefore = null, user = null, @@ -133,42 +179,60 @@ PostSchema.statics = { type = null, tags = [], categories = [], - search = null + topic = null, + search = null, + transcripts = null } = {}) { - const query = {}; + const limitOption = parseInt(limit, 10); + + let query = {}; + // @TODO use let numberOfPages = 0; //eslint-disable-line - let dateDirection = -1; - if (createdAtBefore) query.date = { $lt: moment(createdAtBefore).toDate() }; + + if (createdAtBefore) { + query.date = { + $lt: moment(createdAtBefore).toDate(), + }; + } + if (createdAfter) { dateDirection = 1; - query.date = { $gt: moment(createdAfter).toDate() }; + query.date = { + $gt: moment(createdAfter).toDate(), + }; } if (tags.length > 0) query.tags = { $all: tags }; if (categories.length > 0) query.categories = { $all: categories }; - if (search) { - const titleSearch = {}; - const searchWords = search.split(' ').join('|'); - titleSearch['title.rendered'] = { - $regex: new RegExp(`${searchWords}`, 'i') - }; - - // @TODO: Add this when content doesn't have so much extra data - // let contentSearch = {} - // contentSearch['content.rendered'] = { $regex: new RegExp(`${search}`, 'i') }; + if (query.slugs && query.slugs.length) query.slug = { $in: slugs }; + if (topic) query.topics = { $in: topic }; - query.$or = [titleSearch]; + if (search) { + try { + query = await getSearchQuery({ + search, + limit, + createdAtBefore, + }); + } catch (err) { + console.error(err); //eslint-disable-line + } } - const limitOption = parseInt(limit, 10); + if (transcripts === 'true') { + query.transcriptUrl = { $exists: true }; + } else if (transcripts === 'false') { + query.transcriptUrl = { $exists: false }; + } let sort = { date: dateDirection }; if (type === 'top') { sort = { score: -1 }; } + const queryPromise = this.find(query, this.standardSelectForFind) .populate('thread') .sort(sort) @@ -178,6 +242,7 @@ PostSchema.statics = { if (dateDirection === 1) { queryPromise.sort({ date: -1 }); } + if (!user) { return queryPromise.then(postsFound => postsFound); } @@ -190,7 +255,7 @@ PostSchema.statics = { // .lean() // returns as plain object, but this will remove deafault values which is bad .exec() .then((postsFound) => { - // add bookmarked + // add bookmarked const postsWithBookmarked = postsFound.map((post) => { const _post = post; const { bookmarkedByUser } = _post; @@ -198,14 +263,17 @@ PostSchema.statics = { delete _post.bookmarkedByUser; return Object.assign({}, post.toObject(), { bookmarked }); }); + // add vote info return this.addVotesForUserToPosts(postsWithBookmarked, user._id); }); }, + addVotesForUserToPosts(posts, userId) { - const postIds = posts.map((post) => { //eslint-disable-line + const postIds = posts.map((post) => { return post._id; }); + return Vote.find({ $or: [ { @@ -255,4 +323,4 @@ PostSchema.statics = { PostSchema.index({ 'title.rendered': 'text', 'content.rendered': 'text' }); -export default mongoose.model('Post', PostSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Post`, PostSchema); diff --git a/server/models/postSubscription.model.js b/server/models/postSubscription.model.js new file mode 100644 index 00000000..fe8448da --- /dev/null +++ b/server/models/postSubscription.model.js @@ -0,0 +1,22 @@ +import mongoose, { Schema } from 'mongoose'; +import config from '../../config/config'; + +/** + * Schema + */ +const postSubscriptionSchema = new mongoose.Schema({ + user: { + type: Schema.Types.ObjectId, + ref: 'User' + }, + post: { + type: Schema.Types.ObjectId, + ref: 'Post' + }, + dateCreated: { + type: Date, + default: Date.now + } +}); + +export default mongoose.model(`${config.mongo.collectionPrefix}PostSubscription`, postSubscriptionSchema); diff --git a/server/models/question.model.js b/server/models/question.model.js new file mode 100644 index 00000000..b27948c5 --- /dev/null +++ b/server/models/question.model.js @@ -0,0 +1,18 @@ +import mongoose from 'mongoose'; +import config from '../../config/config'; + +// Create schema +const QuestionSchema = new mongoose.Schema({ + entityId: { type: String }, + author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + entityType: { type: String }, + content: { type: String }, + dateCreated: { type: Date, default: Date.now }, + dateUpdated: { type: Date, default: Date.now }, + answers: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Answer' }], + deleted: { type: Boolean }, + order: { type: Number }, +}); + +// Export the model +module.exports = mongoose.model(`${config.mongo.collectionPrefix}Question`, QuestionSchema); diff --git a/server/models/relatedLink.model.js b/server/models/relatedLink.model.js index 4295a55f..1d9cdd1e 100644 --- a/server/models/relatedLink.model.js +++ b/server/models/relatedLink.model.js @@ -1,5 +1,6 @@ import mongoose, { Schema } from 'mongoose'; import Vote from './vote.model'; +import config from '../../config/config'; /** * @swagger * definitions: @@ -18,6 +19,10 @@ import Vote from './vote.model'; * type: string * description: Related URL * example: google.com + * type: + * type: string + * description: Type of related content + * example: link, episode * clicks: * type: number * description: Number of clicks this url has received @@ -37,10 +42,17 @@ const RelatedLinkSchema = new Schema({ type: String, required: true }, + icon: { + type: String, + }, title: { type: String, required: true }, + type: { + type: String, + default: 'link', + }, image: { type: String }, clicks: { type: Number, default: 0 }, score: { type: Number, default: 0 }, @@ -56,6 +68,14 @@ const RelatedLinkSchema = new Schema({ type: Schema.Types.ObjectId, ref: 'Post' }, + topicPage: { + type: Schema.Types.ObjectId, + ref: 'TopicPage' + }, + entityType: { + type: String, + default: 'post' + }, author: { type: Schema.Types.ObjectId, ref: 'User' @@ -110,4 +130,4 @@ RelatedLinkSchema.statics = { RelatedLinkSchema.index({ url: 'text' }); exports.RelatedLinkSchema = RelatedLinkSchema; -export default mongoose.model('RelatedLink', RelatedLinkSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}RelatedLink`, RelatedLinkSchema); diff --git a/server/models/subscription.model.js b/server/models/subscription.model.js index 266f3f13..64b3593e 100644 --- a/server/models/subscription.model.js +++ b/server/models/subscription.model.js @@ -1,4 +1,5 @@ import mongoose, { Schema } from 'mongoose'; +import config from '../../config/config'; /** * Schema @@ -23,4 +24,4 @@ const SubscriptionSchema = new mongoose.Schema({ // TODO: date expired??? }); -export default mongoose.model('Subscription', SubscriptionSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Subscription`, SubscriptionSchema); diff --git a/server/models/tag.model.js b/server/models/tag.model.js index 96ea54b4..217bf618 100644 --- a/server/models/tag.model.js +++ b/server/models/tag.model.js @@ -2,6 +2,7 @@ import Promise from 'bluebird'; import mongoose from 'mongoose'; import httpStatus from 'http-status'; import APIError from '../helpers/APIError'; +import config from '../../config/config'; /** * TODO: Add swagger doc @@ -58,4 +59,4 @@ TagSchema.statics = { /** * @typedef Tag */ -export default mongoose.model('Tag', TagSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Tag`, TagSchema); diff --git a/server/models/topic.model.js b/server/models/topic.model.js new file mode 100644 index 00000000..5d59e092 --- /dev/null +++ b/server/models/topic.model.js @@ -0,0 +1,31 @@ +import mongoose from 'mongoose'; +import config from '../../config/config'; + +const slug = require('mongoose-slug-generator'); + +mongoose.plugin(slug); + +// Create schema +const TopicSchema = new mongoose.Schema({ + name: { + type: String, + unique: true + }, + slug: { type: String, slug: 'name', unique: true }, + maintainer: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + maintainers: [ + { type: mongoose.Schema.Types.ObjectId, ref: 'User' } + ], + topicPage: { type: mongoose.Schema.Types.ObjectId, ref: 'TopicPage' }, + postCount: { type: Number, default: 0 }, + status: { type: String, default: 'active' }, + isUserGenerated: { type: Boolean, default: false }, +}, { + timestamps: { + createdAt: 'dateCreated', + updatedAt: 'dateUpdated', + }, +}); + +// Export the model +module.exports = mongoose.model(`${config.mongo.collectionPrefix}Topic`, TopicSchema); diff --git a/server/models/topicPage.model.js b/server/models/topicPage.model.js new file mode 100644 index 00000000..786f74c3 --- /dev/null +++ b/server/models/topicPage.model.js @@ -0,0 +1,42 @@ +import mongoose from 'mongoose'; +import config from '../../config/config'; + +const TopicPageHistorySchema = new mongoose.Schema({ + user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + event: { type: String }, + revision: { type: Number }, + dateCreated: { type: Date, default: Date.now }, +}); + +const TopicPageImageSchema = new mongoose.Schema({ + createdBy: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + url: { type: String }, + deleted: { type: Boolean, default: false }, + dateCreated: { type: Date, default: Date.now }, +}); + +const TopicPageSchema = new mongoose.Schema({ + topic: { type: mongoose.Schema.Types.ObjectId, ref: 'Topic' }, + content: { type: String }, + dateCreated: { type: Date, default: Date.now }, + dateUpdated: { type: Date, default: Date.now }, + logo: { type: String, default: '' }, + published: { type: Boolean, default: false }, + revision: { type: Number }, + lastRevision: { type: Number }, + twitterAccounts: { type: Array, default: [] }, + history: [TopicPageHistorySchema], + images: [TopicPageImageSchema], + searchIndex: { type: String }, +}); + +TopicPageSchema.pre('save', function onSave(next) { + const doc = this; + doc.dateUpdated = Date.now; + next(); +}); + +// Export the model +module.exports = mongoose.model(`${config.mongo.collectionPrefix}TopicPage`, TopicPageSchema); +module.exports.History = mongoose.model(`${config.mongo.collectionPrefix}TopicPageHistory`, TopicPageHistorySchema); +module.exports.Image = mongoose.model(`${config.mongo.collectionPrefix}TopicPageImage`, TopicPageImageSchema); diff --git a/server/models/topicPageRevision.model.js b/server/models/topicPageRevision.model.js new file mode 100644 index 00000000..e58f7ec3 --- /dev/null +++ b/server/models/topicPageRevision.model.js @@ -0,0 +1,14 @@ +import mongoose from 'mongoose'; +import config from '../../config/config'; + +const TopicPageRevisionSchema = new mongoose.Schema({ + topicPage: { type: mongoose.Schema.Types.ObjectId, ref: 'TopicPage' }, + author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, + content: { type: String }, + logo: { type: String, default: '' }, + revision: { type: Number, }, + dateCreated: { type: Date, default: Date.now }, +}); + +// Export the model +module.exports = mongoose.model(`${config.mongo.collectionPrefix}TopicPageRevision`, TopicPageRevisionSchema); diff --git a/server/models/topicSubscription.model.js b/server/models/topicSubscription.model.js new file mode 100644 index 00000000..c10f44ef --- /dev/null +++ b/server/models/topicSubscription.model.js @@ -0,0 +1,22 @@ +import mongoose, { Schema } from 'mongoose'; +import config from '../../config/config'; + +/** + * Schema + */ +const topicSubscriptionSchema = new mongoose.Schema({ + user: { + type: Schema.Types.ObjectId, + ref: 'User' + }, + topic: { + type: Schema.Types.ObjectId, + ref: 'Topic' + }, + dateCreated: { + type: Date, + default: Date.now + } +}); + +export default mongoose.model(`${config.mongo.collectionPrefix}TopicSubscription`, topicSubscriptionSchema); diff --git a/server/models/user.model.js b/server/models/user.model.js index 74700860..a38a0207 100644 --- a/server/models/user.model.js +++ b/server/models/user.model.js @@ -3,6 +3,7 @@ import mongoose, { Schema } from 'mongoose'; import httpStatus from 'http-status'; import bcrypt from 'bcrypt-nodejs'; import APIError from '../helpers/APIError'; +import config from '../../config/config'; /** * User Schema @@ -28,6 +29,9 @@ const UserSchema = new mongoose.Schema({ type: String // , required: true // Should be requied but need to update all clients }, + lastName: { + type: String + }, avatarUrl: { type: String }, @@ -57,6 +61,14 @@ const UserSchema = new mongoose.Schema({ type: Boolean, default: false }, + isSuperAdmin: { + type: Boolean, + default: false + }, + blockedTopicEdit: { + type: Boolean, + default: false + }, email: { type: String }, @@ -77,6 +89,9 @@ const UserSchema = new mongoose.Schema({ type: String } }, + topics: { + type: Array + }, emailNotiicationSettings: { unsubscribedFromThreads: { type: Boolean, @@ -104,7 +119,10 @@ const UserSchema = new mongoose.Schema({ createdAt: { type: Date, default: Date.now - } + }, + rss: { + type: String + }, }); /** @@ -123,6 +141,11 @@ UserSchema.method({ } }); +UserSchema.pre('save', function (next) { + this.dateUpdated = Date.now; + next(); +}); + /** * Statics */ @@ -166,10 +189,11 @@ UserSchema.statics = { isValidHash: function validPassword({ original, hash }) { return bcrypt.compareSync(original, hash); }, - updatableFields: ['username', 'website', 'bio', 'publicEmail', 'twitter', 'github', 'linkedin', 'about', 'name', 'email'] + + updatableFields: ['username', 'website', 'bio', 'publicEmail', 'twitter', 'github', 'linkedin', 'about', 'name', 'lastName', 'email'] }; /** * @typedef User */ -export default mongoose.model('User', UserSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}User`, UserSchema); diff --git a/server/models/vote.model.js b/server/models/vote.model.js index 0212420f..7a388876 100644 --- a/server/models/vote.model.js +++ b/server/models/vote.model.js @@ -2,6 +2,7 @@ import Promise from 'bluebird'; import mongoose from 'mongoose'; import httpStatus from 'http-status'; import APIError from '../helpers/APIError'; +import config from '../../config/config'; /** * @swagger @@ -120,4 +121,4 @@ VoteSchema.statics = { /** * @typedef Vote */ -export default mongoose.model('Vote', VoteSchema); +export default mongoose.model(`${config.mongo.collectionPrefix}Vote`, VoteSchema); diff --git a/server/package-lock.json b/server/package-lock.json deleted file mode 100644 index 48e341a0..00000000 --- a/server/package-lock.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "lockfileVersion": 1 -} diff --git a/server/routes/answer.route.js b/server/routes/answer.route.js new file mode 100644 index 00000000..6699480b --- /dev/null +++ b/server/routes/answer.route.js @@ -0,0 +1,20 @@ +import express from 'express'; +import expressJwt from 'express-jwt'; +import answerCtrl from '../controllers/answer.controller'; +import config from '../../config/config'; + +const router = express.Router(); +const jwt = expressJwt({ secret: config.jwtSecret }); + +router.route('/') + .post(jwt, answerCtrl.create); + +router.route('/:id') + .get(answerCtrl.get) + .put(jwt, answerCtrl.update) + .delete(jwt, answerCtrl.delete); + +router.route('/:id/vote') + .post(jwt, answerCtrl.vote); + +export default router; diff --git a/server/routes/auth.route.js b/server/routes/auth.route.js index 86f4509b..e7a5e91b 100644 --- a/server/routes/auth.route.js +++ b/server/routes/auth.route.js @@ -13,7 +13,21 @@ router.route('/login').post(validate(paramValidation.login), authCtrl.login); router .route('/loginWithEmail') - .post(validate(paramValidation.loginWithEmail), authCtrl.loginWithEmail); + .post( + validate(paramValidation.loginWithEmail), + authCtrl.loginWithEmail + ); + +router + .route('/twitter-request') + .post(authCtrl.twitterRequest); + +router + .route('/twitter-access') + .post( + authCtrl.twitterAccess, + authCtrl.register + ); router.route('/register').post(validate(paramValidation.register), authCtrl.register); @@ -31,4 +45,6 @@ router router.route('/facebook/token').post(passport.authenticate('facebook-token'), authCtrl.socialAuth); +router.route('/recaptcha').post(authCtrl.validateRecaptcha); + export default router; diff --git a/server/routes/comment.route.js b/server/routes/comment.route.js index 66b56f94..37f85fc7 100644 --- a/server/routes/comment.route.js +++ b/server/routes/comment.route.js @@ -19,9 +19,9 @@ router.route('/forEntity/:entityId') commentCtrl.list ) .post( - expressJwt({ secret: config.jwtSecret }) - , validate(paramValidation.comment) - , commentCtrl.create + expressJwt({ secret: config.jwtSecret }), + validate(paramValidation.comment), + commentCtrl.create ); router.route('/:commentId/upvote') diff --git a/server/routes/index.route.js b/server/routes/index.route.js index 0eab28d0..b17c4a57 100644 --- a/server/routes/index.route.js +++ b/server/routes/index.route.js @@ -14,6 +14,14 @@ import subscriptionRoutes from './subscription.route'; import forumRoutes from './forum.route'; import listenedRoutes from './listened.route'; import tagsRoutes from './tag.route'; +import topicsRoutes from './topics.route'; +import topicRoutes from './topic.route'; +import rssRoutes from './rss.route'; +import profileRoutes from './profile.route'; +import topicPageRoutes from './topicPage.route'; +import questionRoutes from './question.route'; +import answerRoutes from './answer.route'; +import twitterRoutes from './twitter.route'; // import userRoutes from './user.route'; const router = express.Router(); // eslint-disable-line new-cap @@ -49,7 +57,6 @@ router.use('/companies', companyRoutes); router.use('/comments', commentRoutes); router.use('/votes', voteRoutes); router.use('/bookmarks', bookmarkRoutes); -// todo: deprecate once all clients use bookmarks router.use('/favorites', bookmarkRoutes); router.use('/listened', listenedRoutes); router.use('/tags', tagsRoutes); @@ -57,5 +64,13 @@ router.use('/users', userRoutes); router.use('/subscription', subscriptionRoutes); router.use('/feed', feedRoutes); router.use('/auth', authRoutes); +router.use('/topics', topicsRoutes); +router.use('/topic', topicRoutes); +router.use('/rss', rssRoutes); +router.use('/profile', profileRoutes); +router.use('/topicpage', topicPageRoutes); +router.use('/question', questionRoutes); +router.use('/answer', answerRoutes); +router.use('/twitter', twitterRoutes); export default router; diff --git a/server/routes/post.route.js b/server/routes/post.route.js index 796f9de7..2f3d2b5f 100644 --- a/server/routes/post.route.js +++ b/server/routes/post.route.js @@ -1,89 +1,161 @@ import express from 'express'; import expressJwt from 'express-jwt'; import validate from 'express-validation'; +import omit from 'lodash/omit'; import paramValidation from '../../config/param-validation'; import postCtrl from '../controllers/post.controller'; import voteCtrl from '../controllers/vote.controller'; +import likeCtrl from '../controllers/like.controller'; import transferField from '../middleware/transferField'; import relatedLinkCtrl from '../controllers/relatedLink.controller'; import bookmarkCtrl from '../controllers/bookmark.controller'; import listenedCtrl from '../controllers/listened.controller'; +import questionCtrl from '../controllers/question.controller'; +import answerCtrl from '../controllers/answer.controller'; import config from '../../config/config'; import loadFullUser from '../middleware/loadFullUser.middleware'; +import respond from '../middleware/response.middleware'; const router = express.Router(); // eslint-disable-line new-cap +// @TODO: Remove this after it's fixed in iOS +const jwtCleanUp = (req, res, next) => { + if (req.headers.authorization && !req.headers.authorization.split(' ')[1]) { + req.headers = omit(req.headers, 'authorization'); + } + next(); +}; + router.route('/') .get( - expressJwt({ secret: config.jwtSecret, credentialsRequired: false }) - , loadFullUser - , postCtrl.list + jwtCleanUp, + expressJwt({ + secret: config.jwtSecret, + credentialsRequired: false, + }), + loadFullUser, + answerCtrl.list, + postCtrl.list, + ); + +router.route('/popular') + .get(postCtrl.popular); + +router.route('/search') + .get( + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + loadFullUser, + postCtrl.search, ); router.route('/recommendations') .get( - expressJwt({ secret: config.jwtSecret }) - , loadFullUser - , postCtrl.recommendations + expressJwt({ secret: config.jwtSecret }), + loadFullUser, + postCtrl.recommendations, ); router.route('/:postId') .get( - expressJwt({ secret: config.jwtSecret, credentialsRequired: false }) - , loadFullUser - , postCtrl.get + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + loadFullUser, + postCtrl.get, + questionCtrl.getRelated, + respond, + ); + +router.route('/:postId/topics') + .put( + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + postCtrl.get, + postCtrl.updateTopics, + ); + +router.route('/:postId/related-episodes') + .get( + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + postCtrl.getRelatedEpisodes, + ); + +router.route('/:postId/related-episodes/:episodeSlug') + .post( + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + postCtrl.load, + postCtrl.saveRelatedEpisode, + ) + .delete( + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + postCtrl.load, + postCtrl.deleteRelatedEpisode, ); + // Get related links associated with postId router.route('/:postId/related-links') .get( - expressJwt({ secret: config.jwtSecret, credentialsRequired: false }) - , relatedLinkCtrl.list + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + relatedLinkCtrl.list, ); // Add a related-link to postId: router.route('/:postId/related-link') .post( - expressJwt({ secret: config.jwtSecret }) - , validate(paramValidation.relatedLinkCreate) - , relatedLinkCtrl.create + expressJwt({ secret: config.jwtSecret }), + validate(paramValidation.relatedLinkCreate), + relatedLinkCtrl.create, + ); + +router.route('/:postId/like') + .post( + expressJwt({ secret: config.jwtSecret }), + likeCtrl.likePost, ); router.route('/:postId/upvote') .post( - expressJwt({ secret: config.jwtSecret }) - , transferField({ source: 'post', target: 'entity' }) - , voteCtrl.findVote - , voteCtrl.upvote // normal upvoting via vote model - , postCtrl.upvote // special-case: uses racoon upvoting just for posts. - , voteCtrl.finish + expressJwt({ secret: config.jwtSecret }), + transferField({ source: 'post', target: 'entity' }), + voteCtrl.findVote, + voteCtrl.upvote, // normal upvoting via vote model + voteCtrl.finish, ); router.route('/:postId/downvote') .post( - expressJwt({ secret: config.jwtSecret }) - , transferField({ source: 'post', target: 'entity' }) - , voteCtrl.findVote - , voteCtrl.downvote - , postCtrl.downvote - , voteCtrl.finish + expressJwt({ secret: config.jwtSecret }), + transferField({ source: 'post', target: 'entity' }), + voteCtrl.findVote, + voteCtrl.downvote, + voteCtrl.finish, ); router.route('/:postId/bookmark') - .post(expressJwt({ secret: config.jwtSecret }), bookmarkCtrl.bookmark); + .post( + expressJwt({ secret: config.jwtSecret }), + bookmarkCtrl.bookmark, + ); // todo: deprecate once all clients use bookmark router.route('/:postId/favorite') .post(expressJwt({ secret: config.jwtSecret }), bookmarkCtrl.bookmark); router.route('/:postId/unbookmark') - .post(expressJwt({ secret: config.jwtSecret }), bookmarkCtrl.unbookmark); + .post( + expressJwt({ secret: config.jwtSecret }), + bookmarkCtrl.unbookmark, + ); // todo: deprecate once all clients use unbookmark router.route('/:postId/unfavorite') - .post(expressJwt({ secret: config.jwtSecret }), bookmarkCtrl.unbookmark); + .post( + expressJwt({ secret: config.jwtSecret }), + bookmarkCtrl.unbookmark, + ); router.route('/:postId/listened') - .post(expressJwt({ secret: config.jwtSecret }), listenedCtrl.create); + .post( + expressJwt({ secret: config.jwtSecret }), + listenedCtrl.create, + ); router.param('postId', postCtrl.load); diff --git a/server/routes/profile.route.js b/server/routes/profile.route.js new file mode 100644 index 00000000..737255f8 --- /dev/null +++ b/server/routes/profile.route.js @@ -0,0 +1,10 @@ +import express from 'express'; +import profileCtrl from '../controllers/profile.controller'; + +const router = express.Router(); + +router.route('/:profileId').get(profileCtrl.getPublic); + +router.route('/activities/:userId').get(profileCtrl.getActivities); + +export default router; diff --git a/server/routes/question.route.js b/server/routes/question.route.js new file mode 100644 index 00000000..b8863262 --- /dev/null +++ b/server/routes/question.route.js @@ -0,0 +1,28 @@ +import express from 'express'; +import expressJwt from 'express-jwt'; +import questionCtrl from '../controllers/question.controller'; +import loadFullUser from '../middleware/loadFullUser.middleware'; +import config from '../../config/config'; + +const router = express.Router(); +const jwt = expressJwt({ secret: config.jwtSecret }); + +router.route('/') +// .get(jwt, questionCtrl.search) // if needed in admin + .post(jwt, loadFullUser, questionCtrl.create); + +router.route('/unanswered') + .get(questionCtrl.getUnanswered); + +router.route('/:id') + .get(questionCtrl.get) + .put(jwt, loadFullUser, questionCtrl.update) + .delete(jwt, loadFullUser, questionCtrl.delete); + +router.route('/entity/:entityType/:entityId') + .get(questionCtrl.getByEntity); + +router.route('/entity/:entityType/:entityId/order') + .put(questionCtrl.updateOrder); + +export default router; diff --git a/server/routes/rss.route.js b/server/routes/rss.route.js new file mode 100644 index 00000000..499f12aa --- /dev/null +++ b/server/routes/rss.route.js @@ -0,0 +1,12 @@ +import express from 'express'; +import rssCtrl from '../controllers/rss.controller'; + +const router = express.Router(); + +router.route('/public/all_unlimited').get(rssCtrl.publicFeedAll); + +router.route('/public/all').get(rssCtrl.publicFeed); + +router.route('/private/:id').get(rssCtrl.privateFeed); + +export default router; diff --git a/server/routes/topic.route.js b/server/routes/topic.route.js new file mode 100644 index 00000000..13d9cd54 --- /dev/null +++ b/server/routes/topic.route.js @@ -0,0 +1,31 @@ +import express from 'express'; +import expressJwt from 'express-jwt'; +import topicCtrl from '../controllers/topic.controller'; +import topicPageCtrl from '../controllers/topicPage.controller'; +import loadFullUser from '../middleware/loadFullUser.middleware'; +import ensureIsAdmin from '../middleware/ensureIsAdmin.middleware'; +import config from '../../config/config'; + +const router = express.Router(); // eslint-disable-line new-cap + +const auth = expressJwt({ secret: config.jwtSecret }); + +router.route('/:topicId([0-9a-f]{24})') // possible conflict with slug route + .get(topicCtrl.get) + .put(auth, loadFullUser, ensureIsAdmin, topicCtrl.update); + +router.route('/') + .get(auth, topicCtrl.getFull) + .post(auth, topicCtrl.add); + +router.route('/:slug') + .get(topicPageCtrl.showContent); + +router.route('/:slug/episodes') + .get(topicCtrl.episodes) + .post(auth, topicCtrl.createRelatedEpisode); + +router.route('/:slug/jobs') + .get(topicCtrl.jobs); + +export default router; diff --git a/server/routes/topicPage.route.js b/server/routes/topicPage.route.js new file mode 100644 index 00000000..c307277e --- /dev/null +++ b/server/routes/topicPage.route.js @@ -0,0 +1,48 @@ +import express from 'express'; +import expressJwt from 'express-jwt'; +import topicPageCtrl from '../controllers/topicPage.controller'; +import topicPageRevisionCtrl from '../controllers/topicPageRevision.controller'; +import config from '../../config/config'; +import loadFullUser from '../middleware/loadFullUser.middleware'; + +const router = express.Router(); +const auth = expressJwt({ secret: config.jwtSecret }); + +router.route('/recentPages') + .get(topicPageCtrl.recentPages); + +router.route('/:slug') + .get(topicPageCtrl.showContent) + .put(auth, loadFullUser, topicPageCtrl.update); + +router.route('/:slug/publish') + .put(auth, loadFullUser, topicPageCtrl.publish); + +router.route('/:slug/unpublish') + .put(auth, loadFullUser, topicPageCtrl.unpublish); + +router.route('/:slug/edit') + .get(auth, loadFullUser, topicPageCtrl.get); + +router.route('/:slug/revision/:revisionNumber') + .get(auth, loadFullUser, topicPageRevisionCtrl.get) + .post(auth, loadFullUser, topicPageRevisionCtrl.set); + +router.route('/:slug/images') + .get(topicPageCtrl.getImages) + .post( + auth, + loadFullUser, + topicPageCtrl.signS3ImageUpload + ); + +router.route('/:slug/logo') + .post( + auth, + loadFullUser, + topicPageCtrl.signS3LogoUpload + ); + +router.route('/:slug/images/:imageId') + .delete(auth, topicPageCtrl.deleteImage); +export default router; diff --git a/server/routes/topics.route.js b/server/routes/topics.route.js new file mode 100644 index 00000000..a9b035f6 --- /dev/null +++ b/server/routes/topics.route.js @@ -0,0 +1,46 @@ +import express from 'express'; +import expressJwt from 'express-jwt'; +import topicCtrl from '../controllers/topic.controller'; +import loadFullUser from '../middleware/loadFullUser.middleware'; +import config from '../../config/config'; + +const router = express.Router(); // eslint-disable-line new-cap + +const auth = expressJwt({ secret: config.jwtSecret }); + +router.route('/mostPopular') + .get(topicCtrl.mostPopular); + +router.route('/mostPosts') + .get(topicCtrl.mostPosts); + +router.route('/addTopicsToPost') + .post(topicCtrl.addTopicsToPost); + +router.route('/') + .get(topicCtrl.index) + .post(auth, loadFullUser, topicCtrl.create); + +router.route('/full') + .get(topicCtrl.getFull); + +router.route('/addTopicsToUser') + .post(topicCtrl.addTopicsToUser); + +router.route('/searchTopics') + .get(topicCtrl.searchTopics); + +router.route('/top/:count') + .get(topicCtrl.top); + +router.route('/maintainer') + .post(auth, topicCtrl.setMaintainer) + .delete(auth, topicCtrl.removeMaintainer); + +router.route('/:slug') + .get(topicCtrl.show) + // .put(expressJwt({ secret: config.jwtSecret }), topicCtrl.update) + .delete(auth, topicCtrl.deleteTopic); + + +export default router; diff --git a/server/routes/twitter.route.js b/server/routes/twitter.route.js new file mode 100644 index 00000000..930a9643 --- /dev/null +++ b/server/routes/twitter.route.js @@ -0,0 +1,14 @@ +import express from 'express'; +import expressJwt from 'express-jwt'; +import twitterCtrl from '../controllers/twitter.controller'; +import config from '../../config/config'; + +const router = express.Router(); // eslint-disable-line new-cap + +router.route('/users/search') + .get( + expressJwt({ secret: config.jwtSecret }), + twitterCtrl.usersSearch + ); + +export default router; diff --git a/server/routes/user.route.js b/server/routes/user.route.js index 312b7c66..37b0b597 100644 --- a/server/routes/user.route.js +++ b/server/routes/user.route.js @@ -4,43 +4,76 @@ import validate from 'express-validation'; import paramValidation from '../../config/param-validation'; import userCtrl from '../controllers/user.controller'; import loadFullUser from '../middleware/loadFullUser.middleware'; +import ensureIsAdmin from '../middleware/ensureIsAdmin.middleware'; import config from '../../config/config'; const router = express.Router(); // eslint-disable-line new-cap +router.route('/') + .get( + expressJwt({ secret: config.jwtSecret }), + loadFullUser, + ensureIsAdmin, + userCtrl.getAll + ); + +// Admin CRUDE (don't interfere with profile update for now) +router.route('/admin/:userId') + .get( + expressJwt({ secret: config.jwtSecret }), + loadFullUser, + ensureIsAdmin, + userCtrl.adminGet + ) + .put( + expressJwt({ secret: config.jwtSecret }), + loadFullUser, + ensureIsAdmin, + userCtrl.update + ); + router.route('/me') /** GET /api/users/:userId - Get user */ .get( - expressJwt({ secret: config.jwtSecret }) - , userCtrl.me + expressJwt({ secret: config.jwtSecret }), + userCtrl.me ); router.route('/search') .get( - expressJwt({ secret: config.jwtSecret }) - , loadFullUser - , userCtrl.list + expressJwt({ secret: config.jwtSecret }), + loadFullUser, + userCtrl.list + ); + +router.route('/search/names') + .get( + expressJwt({ secret: config.jwtSecret }), + userCtrl.listNames ); router.route('/update-email-notiication-settings') .put( - expressJwt({ secret: config.jwtSecret }) - , loadFullUser - , validate(paramValidation.updateEmailNotiicationSettings) - , userCtrl.updateEmailNotiicationSettings + expressJwt({ secret: config.jwtSecret }), + loadFullUser, + validate(paramValidation.updateEmailNotiicationSettings), + userCtrl.updateEmailNotiicationSettings ); router.route('/:userId') - /** GET /api/users/:userId - Get user */ .get( - expressJwt({ secret: config.jwtSecret, credentialsRequired: false }) - , userCtrl.get + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + userCtrl.get ) - - /** PUT /api/users/:userId - Update user */ .put( - expressJwt({ secret: config.jwtSecret }) - , validate(paramValidation.updateUser), userCtrl.update + expressJwt({ secret: config.jwtSecret }), + validate(paramValidation.updateUser), userCtrl.updateProfile + ); + +router.route('/:userId/topics') + .get( + expressJwt({ secret: config.jwtSecret, credentialsRequired: false }), + userCtrl.getTopics ); router.route('/regain-password') @@ -56,14 +89,18 @@ router.route('/request-password-reset') ); router.route('/me/bookmarked') -/** GET /api/users/me/bookmarked - Get bookmarked items for current user */ .get( - expressJwt({ secret: config.jwtSecret }) - , userCtrl.listBookmarked + expressJwt({ secret: config.jwtSecret }), + userCtrl.listBookmarked + ); + +router.route('/me/bookmarked/:postId') + .delete( + expressJwt({ secret: config.jwtSecret }), + userCtrl.removeBookmarked ); router.route('/:userId/bookmarked') -/** GET /api/users/:userId/bookmarked - Get bookmarked items for specified user */ .get(userCtrl.listBookmarked); /** Load user when API with userId route parameter is hit */ diff --git a/server/templates/email/sd-body-post-comment-author.handlebars b/server/templates/email/sd-body-post-comment-author.handlebars new file mode 100644 index 00000000..22b6b9c9 --- /dev/null +++ b/server/templates/email/sd-body-post-comment-author.handlebars @@ -0,0 +1,20 @@ +{{#> sd-simple-template }} +

New comment

+

Hi {{user}},

+

{{commenter.name}} commented on your {{entityName}}.

+ +{{> sd-template-comment}} + + + + + +
+

+ Go to {{entityName}} +

+
+ +{{/sd-simple-template}} \ No newline at end of file diff --git a/server/templates/email/sd-body-post-comment-mention.handlebars b/server/templates/email/sd-body-post-comment-mention.handlebars new file mode 100644 index 00000000..20452d01 --- /dev/null +++ b/server/templates/email/sd-body-post-comment-mention.handlebars @@ -0,0 +1,20 @@ +{{#> sd-simple-template }} +

New mention

+

Hi {{user}},

+

{{commenter.name}} mentioned you in a comment.

+ +{{> sd-template-comment}} + + + + + +
+

+ Go to {{entityName}} +

+
+ +{{/sd-simple-template}} \ No newline at end of file diff --git a/server/templates/email/sd-body-post-comment-reply.handlebars b/server/templates/email/sd-body-post-comment-reply.handlebars new file mode 100644 index 00000000..44c513d3 --- /dev/null +++ b/server/templates/email/sd-body-post-comment-reply.handlebars @@ -0,0 +1,20 @@ +{{#> sd-simple-template }} +

New replied comment

+

Hi {{user}},

+

{{commenter.name}} replied your comment.

+ +{{> sd-template-comment}} + + + + + +
+

+ Go to {{entityName}} +

+
+ +{{/sd-simple-template}} \ No newline at end of file diff --git a/server/templates/email/sd-body-topic-maintainer.handlebars b/server/templates/email/sd-body-topic-maintainer.handlebars new file mode 100644 index 00000000..0b19abf5 --- /dev/null +++ b/server/templates/email/sd-body-topic-maintainer.handlebars @@ -0,0 +1,14 @@ +{{#> sd-simple-template }} +

A new maintainer!

+

Hi {{user}},

+

You have been assigned to write and maintain {{topic}} topic page.

+ + + + +
+

+ Edit page now +

+
+{{/sd-simple-template}} \ No newline at end of file diff --git a/server/templates/email/sd-body-topic-new-answer.handlebars b/server/templates/email/sd-body-topic-new-answer.handlebars new file mode 100644 index 00000000..b4d10973 --- /dev/null +++ b/server/templates/email/sd-body-topic-new-answer.handlebars @@ -0,0 +1,15 @@ +{{#> sd-simple-template}} +

New answer

+

Hi {{user}},

+

Your question has been answered.

+

"{{question}}"

+ + + + +
+

+ {{actionLabel}} +

+
+{{/sd-simple-template}} diff --git a/server/templates/email/sd-body-topic-new-maintainer.handlebars b/server/templates/email/sd-body-topic-new-maintainer.handlebars new file mode 100644 index 00000000..371fada2 --- /dev/null +++ b/server/templates/email/sd-body-topic-new-maintainer.handlebars @@ -0,0 +1,37 @@ +{{#> sd-simple-template }} +

New maintainer

+

Hi {{user}},

+

We have a new maintainer for this topic:

+ + + + +
+ + + + + + + + + + + + + +
+ Topic + + {{topic}} +
+ User Name + + {{maintainer}} +
+ E-mail + + {{email}} +
+
+{{/sd-simple-template}} \ No newline at end of file diff --git a/server/templates/email/sd-body-topic-new-question.handlebars b/server/templates/email/sd-body-topic-new-question.handlebars new file mode 100644 index 00000000..079f7099 --- /dev/null +++ b/server/templates/email/sd-body-topic-new-question.handlebars @@ -0,0 +1,17 @@ +{{#> sd-simple-template}} +

New question

+

Hi {{user}},

+

A new question has been added to {{topic}}.

+{{#each questions}} +

"{{this}}"

+{{/each}} + + + + +
+

+ {{actionLabel}} +

+
+{{/sd-simple-template}} diff --git a/server/templates/email/sd-body-topic-publish.handlebars b/server/templates/email/sd-body-topic-publish.handlebars new file mode 100644 index 00000000..d1892471 --- /dev/null +++ b/server/templates/email/sd-body-topic-publish.handlebars @@ -0,0 +1,46 @@ +{{#> sd-simple-template }} +

New publish status

+

Hi {{user}},

+

We have a new topic page publish status:

+ + + + +
+ + + + + + + + + + + + + +
+ Status + + {{publish}} +
+ Maintainer + + {{maintainer}} +
+ Topic Page + + {{topicPage}} +
+
+ + + + +
+

+ Go to topic +

+
+{{/sd-simple-template}} \ No newline at end of file diff --git a/server/templates/email/sd-simple-body.handlebars b/server/templates/email/sd-simple-body.handlebars new file mode 100644 index 00000000..4d415caf --- /dev/null +++ b/server/templates/email/sd-simple-body.handlebars @@ -0,0 +1,4 @@ +{{#> sd-simple-template }} +

{{title}}

+

{{body}}

+{{/sd-simple-template}} \ No newline at end of file diff --git a/server/templates/email/sd-simple-template.handlebars b/server/templates/email/sd-simple-template.handlebars new file mode 100644 index 00000000..b960fae1 --- /dev/null +++ b/server/templates/email/sd-simple-template.handlebars @@ -0,0 +1,112 @@ + + + + + + + + Software Daily + + + + + + + + + + + +
+ + + + + + + + +
+ +
+ {{> @partial-block }} +
+
+ + + + +
+
+ + diff --git a/server/templates/email/sd-template-comment.handlebars b/server/templates/email/sd-template-comment.handlebars new file mode 100644 index 00000000..424f62eb --- /dev/null +++ b/server/templates/email/sd-template-comment.handlebars @@ -0,0 +1,56 @@ +{{#if comment.parentComment}} + + + + + + + + + + + + +
+
+
+ {{comment.parentComment.author.fullName}} +
+ {{{comment.parentComment.content}}} +
+   + + + + + + + + + +
+
+
+ {{commenter.fullName}} +
+ {{{comment.content}}} +
+
+ +{{else}} + + + + + + + + +
+
+
+ {{commenter.fullName}} +
+ {{{comment.content}}} +
+{{/if}} \ No newline at end of file diff --git a/server/tests/auth.test.js b/server/tests/auth.test.js index 936e8398..0a537f66 100644 --- a/server/tests/auth.test.js +++ b/server/tests/auth.test.js @@ -16,15 +16,26 @@ describe('## Auth APIs', () => { name: 'Software Dev', password: 'express' }; + const validEmailAsUsernameLogin = { username: 'react2@email.com', password: 'express' }; + const validEmailWithUppercaseAsUsernameLogin = { + username: 'React2@email.com', + password: 'express' + }; + const validEmailLogin = { email: 'react2@email.com', password: 'express' }; + const validEmailWithUppercaseLogin = { + email: 'React2@email.com', + password: 'express' + }; + const invalidEmailLogin = { email: 'react2@email.com', @@ -37,6 +48,11 @@ describe('## Auth APIs', () => { password: 'express' }; + const validUserCredentialsWithUppercase = { + username: 'React', + password: 'express' + }; + const invalidUserCredentials = { username: 'react', }; @@ -46,6 +62,14 @@ describe('## Auth APIs', () => { password: 'wrong', }; + // case insensitive check: lowercase email already registered - with unique username + const invalidRegisterWithEmailUppercaseUniqueUsername = { + username: 'react3', + email: 'React2@email.com', + name: 'Software Dev', + password: 'express' + }; + let jwtToken; afterEach((done) => { @@ -55,7 +79,7 @@ describe('## Auth APIs', () => { }); }); - // loingWithEmail + // loginWithEmail describe('# POST /api/auth/register (with email & name)', () => { it('should get valid JWT token', (done) => { request(app) @@ -82,6 +106,33 @@ describe('## Auth APIs', () => { }); }); + // loginWithEmailWithUppercase CASE INSENSITIVE + describe('# POST /api/auth/register * CASE INSENSITIVE * (with email & name)', () => { + it('should get valid JWT token', (done) => { + request(app) + .post('/api/auth/register') + .send(validUserCredentialsWithEmail) + .expect(httpStatus.CREATED) + // We make sure we actually login: + .then((res) => { //eslint-disable-line + return request(app) + .post('/api/auth/loginWithEmail') + .send(validEmailWithUppercaseLogin) + .expect(httpStatus.OK); + }) + .then((res) => { + expect(res.body).to.have.property('token'); + jwt.verify(res.body.token, config.jwtSecret, (err, decoded) => { + expect(err).to.not.be.ok; // eslint-disable-line no-unused-expressions + expect(decoded.username).to.equal(validUserCredentialsWithEmail.username); + jwtToken = `Bearer ${res.body.token}`; + done(); + }); + }) + .catch(done); + }); + }); + describe('# POST /api/auth/loginWithEmail', () => { it('should return Authentication error', (done) => { request(app) @@ -153,6 +204,33 @@ describe('## Auth APIs', () => { }); }); + // CASE INSENSITIVE + describe('# POST /api/auth/register * CASE INSENSITIVE * (+ login with email field as username) ', () => { + it('should get valid JWT token', (done) => { + request(app) + .post('/api/auth/register') + .send(validUserCredentialsWithEmail) + .expect(httpStatus.CREATED) + // We make sure we actually login: + .then((res) => { //eslint-disable-line + return request(app) + .post('/api/auth/login') + .send(validEmailWithUppercaseAsUsernameLogin) + .expect(httpStatus.OK); + }) + .then((res) => { + expect(res.body).to.have.property('token'); + jwt.verify(res.body.token, config.jwtSecret, (err, decoded) => { + expect(err).to.not.be.ok; // eslint-disable-line no-unused-expressions + expect(decoded.username).to.equal(validUserCredentialsWithEmail.username); + jwtToken = `Bearer ${res.body.token}`; + done(); + }); + }) + .catch(done); + }); + }); + describe('# POST /api/auth/login fail on not including username field', () => { it('should return Authentication error', (done) => { request(app) @@ -206,6 +284,43 @@ describe('## Auth APIs', () => { }) .catch(done); }); + + it('should return User already exists error (same valid credentials)', (done) => { + request(app) + .post('/api/auth/register') + .send(validUserCredentialsWithEmail) + .expect(httpStatus.CREATED) + .then((res) => { //eslint-disable-line + return request(app) + .post('/api/auth/register') + .send(validUserCredentialsWithEmail) + .expect(httpStatus.UNAUTHORIZED); + }) + .then((res) => { + expect(res.body.message).to.equal('User already exists.'); + done(); + }) + .catch(done); + }); + + // CASE INSENSITIVE - lowercase email already registered - with unique username + it('should return User already exists error - changing email case should not create new user', (done) => { + request(app) + .post('/api/auth/register') + .send(validUserCredentialsWithEmail) + .expect(httpStatus.CREATED) + .then((res) => { //eslint-disable-line + return request(app) + .post('/api/auth/register') + .send(invalidRegisterWithEmailUppercaseUniqueUsername) + .expect(httpStatus.UNAUTHORIZED); + }) + .then((res) => { + expect(res.body.message).to.equal('User already exists.'); + done(); + }) + .catch(done); + }); }); describe('# POST /api/auth/login', () => { @@ -239,7 +354,7 @@ describe('## Auth APIs', () => { .catch(done); }); - it('should get valid JWT token', (done) => { + it('should get valid JWT token - successful login', (done) => { request(app) .post('/api/auth/register') .send(validUserCredentials) @@ -261,6 +376,30 @@ describe('## Auth APIs', () => { }) .catch(done); }); + + // CASE INSENSITIVE + it('should get valid JWT token - CASE INSENSITIVE successful login', (done) => { + request(app) + .post('/api/auth/register') + .send(validUserCredentials) + .expect(httpStatus.CREATED) + .then((res) => { //eslint-disable-line + return request(app) + .post('/api/auth/login') + .send(validUserCredentialsWithUppercase) + .expect(httpStatus.OK); + }) + .then((res) => { + expect(res.body).to.have.property('token'); + jwt.verify(res.body.token, config.jwtSecret, (err, decoded) => { + expect(err).to.not.be.ok; // eslint-disable-line no-unused-expressions + expect(decoded.username).to.equal(validUserCredentials.username); + jwtToken = `Bearer ${res.body.token}`; + done(); + }); + }) + .catch(done); + }); }); describe('# GET /api/auth/random-number', () => { diff --git a/server/tests/bookmark.test.js b/server/tests/bookmark.test.js index 9416e1f0..89bb1bbf 100644 --- a/server/tests/bookmark.test.js +++ b/server/tests/bookmark.test.js @@ -332,6 +332,8 @@ describe('## Bookmark APIs', () => { it('should include Post score even if undefined', (done) => { // let postIdNoScore; const postNoScore = new Post(); + postNoScore.name = 'Bookmark no score test name'; + postNoScore.slug = 'bookmark-no-score-test-name'; postNoScore.score = undefined; expect(postNoScore.toObject()).to.not.have.keys('score'); postNoScore.save().then(post => post._id).then((postIdNoScore) => { diff --git a/server/tests/post.test.js b/server/tests/post.test.js index e0dafd23..3d5236b5 100644 --- a/server/tests/post.test.js +++ b/server/tests/post.test.js @@ -5,6 +5,7 @@ import httpStatus from 'http-status'; import chai, { expect } from 'chai'; import app from '../../index'; import Post from '../models/post.model'; +import User from '../models/user.model'; chai.config.includeStack = true; @@ -13,6 +14,10 @@ function saveMongoArrayPromise(model, dataArray) { return Promise.all(dataArray.map(data => model(data).save())); } +function getRandomNumber() { + return (Date.now() + Math.floor(Math.random() * Math.floor(9999999))); +} + /** * root level hooks */ @@ -63,11 +68,22 @@ describe('## Post APIs', () => { let firstSet = []; const limitNum = 5; + + const postsArray = []; + for (let i = 0; i < limitNum; i += 1) { + postsArray.push({ + date: moment().subtract(1, 'minutes'), + name: `Posts should get all posts ${getRandomNumber()}`, + slug: `posts-should-get-all-posts-${getRandomNumber()}` + }); + } + it('should get all posts', (done) => { const postsArrayPromise = saveMongoArrayPromise( Post, - new Array(limitNum).fill({}).concat(new Array(limitNum).fill({ date: moment().subtract(1, 'minutes') })) + postsArray ); + postsArrayPromise .then((postFound) => { //eslint-disable-line return request(app) @@ -85,7 +101,8 @@ describe('## Post APIs', () => { }); it('should get all posts (with limit and skip)', (done) => { - const createdAtBefore = firstSet[firstSet.length - 1].date; + const createdAtBeforeNotFormatted = moment(firstSet[0].date).add(1, 'minutes'); + const createdAtBefore = moment(createdAtBeforeNotFormatted, moment.ISO_8601).format(); request(app) .get('/api/posts') .query({ limit: limitNum, createdAtBefore }) @@ -93,10 +110,101 @@ describe('## Post APIs', () => { .then((res) => { expect(res.body).to.be.an('array'); expect(res.body).to.have.lengthOf(limitNum); - expect(res.body).to.not.eql(firstSet); + expect(res.body).to.eql(firstSet); + done(); + }) + .catch(done); + }); + }); + + describe('# POST /api/posts/:postId/like', () => { + const validUserCredentials = { + username: 'react', + password: 'express' + }; + + let userToken; + let postId; + + before((done) => { + request(app) + .post('/api/auth/register') + .send(validUserCredentials) + .expect(httpStatus.CREATED) + .then((res) => { + expect(res.body).to.have.property('token'); + userToken = res.body.token; + const post = new Post(); + return post.save(); + }) + .then((post) => { + postId = post._id; done(); }) .catch(done); }); + + after((done) => { + User.remove({}) + .exec() + .then(() => Post.remove({}).exec()) + .then(() => { + done(); + }); + }); + + it('errors when not logged in', (done) => { + request(app) + .post(`/api/posts/${postId}/like`) + .expect(httpStatus.UNAUTHORIZED) + .then((res) => { + expect(res.body).to.exist; //eslint-disable-line + done(); + }); + }); + + it('likes a post', (done) => { + request(app) + .post(`/api/posts/${postId}/like`) + .set('Authorization', `Bearer ${userToken}`) + .expect(httpStatus.OK) + .then((res) => { + const like = res.body; + expect(like).to.have.property('score').that.is.a('number'); + expect(like).to.have.property('upvoted').that.is.a('boolean'); + expect(like.upvoted).to.be.true; //eslint-disable-line + done(); + }) + .catch(done); + }); + + it('toggles the like for a post', (done) => { + request(app) + .post(`/api/posts/${postId}/like`) + .set('Authorization', `Bearer ${userToken}`) + .expect(httpStatus.OK) + .then((res) => { + const like = res.body; + expect(like).to.have.property('score').that.is.a('number'); + expect(like).to.have.property('upvoted').that.is.a('boolean'); + expect(like.upvoted).to.be.false; //eslint-disable-line + done(); + }) + .catch(done); + }); + }); + + xdescribe('# GET /api/posts/search', () => { + it('returns search results', (done) => { + request(app) + .get('/api/posts/search?query=apple&page=0') + .then((res) => { + expect(res.body).to.exist; //eslint-disable-line + expect(res.body.posts).to.have.property('length'); //eslint-disable-line + expect(res.body).to.have.property('isEnd').that.is.a('boolean'); + expect(res.body).to.have.property('nextPage', 1).that.is.a('number'); + done(); + }); + }); }); }); diff --git a/server/tests/relatedLink.test.js b/server/tests/relatedLink.test.js index 4bc0913e..6cac0c17 100644 --- a/server/tests/relatedLink.test.js +++ b/server/tests/relatedLink.test.js @@ -36,8 +36,7 @@ describe('## Post with relatedLink APIs', () => { let postId; const relatedLinkData = { - title: 'Some Awesome Related Link', - url: 'https://news.com/article' + url: 'https://softwareengineeringdaily.com/2020/02/24/infrastructure-management-with-joey-parsons/' }; before((done) => { @@ -89,7 +88,8 @@ describe('## Post with relatedLink APIs', () => { .expect(httpStatus.CREATED) .then((res) => { //eslint-disable-line const relatedLink = res.body; - expect(relatedLink.title).to.eql(relatedLinkData.title); + expect(relatedLink.icon).to.be.a('string'); + expect(relatedLink.title).to.be.a('string'); expect(relatedLink.url).to.eql(relatedLinkData.url); expect(relatedLink.author).to.eql(firstUserId.toString()); expect(relatedLink.post).to.eql(postId.toString()); @@ -129,7 +129,8 @@ describe('## Post with relatedLink APIs', () => { .expect(httpStatus.OK) .then((res) => { const relatedLink = res.body[0]; - expect(relatedLink.title).to.eql(relatedLinkData.title); + expect(relatedLink.icon).to.be.a('string'); + expect(relatedLink.title).to.be.a('string'); expect(relatedLink.url).to.eql(relatedLinkData.url); expect(relatedLink.post).to.eql(postId.toString()); expect(relatedLink.score).to.eql(0); @@ -154,7 +155,8 @@ describe('## Post with relatedLink APIs', () => { .expect(httpStatus.OK) .then((res) => { const relatedLink = res.body[0]; - expect(relatedLink.title).to.eql(relatedLinkData.title); + expect(relatedLink.icon).to.be.a('string'); + expect(relatedLink.title).to.be.a('string'); expect(relatedLink.url).to.eql(relatedLinkData.url); expect(relatedLink.post).to.eql(postId.toString()); expect(relatedLink.score).to.eql(0); diff --git a/server/tests/topic.test.js b/server/tests/topic.test.js new file mode 100644 index 00000000..e387a84c --- /dev/null +++ b/server/tests/topic.test.js @@ -0,0 +1,138 @@ +import mongoose from 'mongoose'; +import moment from 'moment'; +import request from 'supertest-as-promised'; +import httpStatus from 'http-status'; +import chai, { expect } from 'chai'; +import app from '../../index'; +import Topic from '../models/topic.model'; + +const exampleName = 'Example Name'; + +chai.config.includeStack = true; + +function saveMongoArrayPromise(model, dataArray) { + return Promise.all(dataArray.map(data => model(data).save())); +} + +function getRandomNumber() { + return Math.floor(Math.random() * 10000); +} + + +/** + * root level hooks + */ +after((done) => { + mongoose.models = {}; + mongoose.modelSchemas = {}; + mongoose.connection.close(); + done(); +}); + +describe('## Topic APIs', () => { + describe('# POST /api/topics', () => { + it('Create method should create new topic.', (done) => { + const topic = new Topic(); + topic.name = exampleName; + topic.save() + .then((res) => { + expect(res.name).to.equal(topic.name); + expect(res.slug).to.equal(topic.slug); + done(); + }) + .catch(done); + }); + }); + + describe('# GET /api/topics/:topicSlag', () => { + it('Show method should gets a topic details.', (done) => { + Topic.findOne({ name: exampleName }) + .then((topicFound) => { //eslint-disable-line + request(app) + .get(`/api/topics/${topicFound.slug}`) + .expect(httpStatus.OK); + done(); + }) + .catch(done); + }); + }); + + describe('# PUT /api/topics/:topicSlug', () => { + it('Update method should updates a topic.', (done) => { + Topic.findOne({ name: exampleName }) + .then((topic) => { + request(app) + .put(`/api/topics/${topic.slug}`, { status: 'updated' }) + .expect(httpStatus.OK); + done(); + }) + .catch(done); + }); + }); + + describe('# DELETE /api/topics/:topicSlug', () => { + it('Update method should changes topic status for deleted.', (done) => { + Topic.findOne({ name: exampleName }) + .then((topic) => { + request(app) + .delete(`/api/topics/${topic.slug}`) + .expect(httpStatus.OK); + done(); + }) + .catch(done); + }); + }); + + describe('# GET /api/topics/mostPopular', () => { + it('mostPopular method should returns 10 topics with the largest number value of postCount.', (done) => { + try { + request(app) + .delete('/api/topics/mostPopular') + .expect(httpStatus.OK); + done(); + } catch (e) { + console.log(e); //eslint-disable-line + } + }); + }); + + describe('# GET /api/topics/', () => { + before((done) => { //eslint-disable-line + Topic.remove({}, () => { + done(); + }); + }); + + const limitNum = 5; + + const topicsArray = []; + for (let i = 0; i < limitNum; i += 1) { + topicsArray.push({ + date: moment().subtract(1, 'minutes'), + name: `Topics should get all topics ${getRandomNumber()}`, + slug: `topics-should-get-all-topics-${getRandomNumber()}` + }); + } + + it('Index method should returns all topics', (done) => { + const topicsArrayPromise = saveMongoArrayPromise( + Topic, + topicsArray + ); + + topicsArrayPromise + .then((topicFound) => { //eslint-disable-line + return request(app) + .get('/api/topics') + .query({ limit: limitNum }) + .expect(httpStatus.OK); + }) + .then((res) => { + expect(res.body).to.be.an('array'); + expect(res.body).to.have.lengthOf(limitNum); + done(); + }) + .catch(done); + }); + }); +}); diff --git a/server/tests/user.test.js b/server/tests/user.test.js index e73add68..877d58bf 100644 --- a/server/tests/user.test.js +++ b/server/tests/user.test.js @@ -1,7 +1,7 @@ import mongoose from 'mongoose'; import request from 'supertest-as-promised'; import httpStatus from 'http-status'; -import chai, { expect } from 'chai'; +import chai, { expect, assert } from 'chai'; import app from '../../index'; chai.config.includeStack = true; @@ -66,6 +66,34 @@ describe('## User APIs', () => { }); }); + describe('# GET /api/users/search', () => { + it('should get users list', (done) => { + request(app) + .get('/api/users/search?name=') + .set('Authorization', `Bearer ${userToken}`) + .expect(httpStatus.OK) + .then((res) => { + assert(Array.isArray(res.body)); + done(); + }) + .catch(done); + }); + }); + + describe('# GET /api/users/search/names', () => { + it('should get users list', (done) => { + request(app) + .get('/api/users/search/names?name=') + .set('Authorization', `Bearer ${userToken}`) + .expect(httpStatus.OK) + .then((res) => { + assert(Array.isArray(res.body)); + done(); + }) + .catch(done); + }); + }); + // TODO: add a test to make sure we can't update // username to that of an existing user! diff --git a/server/tests/vote.test.js b/server/tests/vote.test.js index f806e80c..4a72a6b5 100644 --- a/server/tests/vote.test.js +++ b/server/tests/vote.test.js @@ -38,6 +38,8 @@ describe('## Vote APIs', () => { expect(res.body).to.have.property('token'); userToken = res.body.token; const post = new Post(); + post.name = 'post name'; + post.slug = 'post-name'; return post.save(); }) .then((post) => { @@ -81,6 +83,8 @@ describe('## Vote APIs', () => { expect(res.body).to.have.property('token'); user2 = res.body.token; const postnew = new Post(); + postnew.name = 'New post name'; + postnew.slug = 'new-post-name'; return postnew.save(); }) .then((post) => { diff --git a/server/tests/vote_post.test.js b/server/tests/vote_post.test.js index e9fa50fb..c02fa22c 100644 --- a/server/tests/vote_post.test.js +++ b/server/tests/vote_post.test.js @@ -38,6 +38,8 @@ describe('## Vote APIs', () => { expect(res.body).to.have.property('token'); userToken = res.body.token; const post = new Post(); + post.name = 'New post name'; + post.slug = 'new-post-name'; return post.save(); }) .then((post) => {