You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airflow.apache.org by as...@apache.org on 2020/06/04 14:45:57 UTC

[airflow] branch master updated: Remove vendored nvd3 and slugify libraries (#9136)

This is an automated email from the ASF dual-hosted git repository.

ash pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/master by this push:
     new 2580b04  Remove vendored nvd3 and slugify libraries (#9136)
2580b04 is described below

commit 2580b049cf3e2f3990e862a1d0a71f9f6784bd39
Author: Ash Berlin-Taylor <as...@firemirror.com>
AuthorDate: Thu Jun 4 15:45:29 2020 +0100

    Remove vendored nvd3 and slugify libraries (#9136)
    
    We pulled in them because slugify _used_ to default to the GPL'd
    `unidecode` module, but since Slugify 3.0[1] it has used text-unidecode
    by first (and only installs the GPL library by an optional extra, not by
    default) so we can now use it.
    
    This lets us upgreade text-unidecode from 1.2 to the latest 1.3, which
    is the version one of dbt's dependencies needs.
    
    [1]: https://github.com/un33k/python-slugify/blob/4.0.0/CHANGELOG.md#300
---
 .coveragerc                                        |   1 -
 .flake8                                            |   2 +-
 .pre-commit-config.yaml                            |  30 +-
 .rat-excludes                                      |   3 -
 LICENSE                                            |   2 +-
 MANIFEST.in                                        |   1 -
 airflow/_vendor/README                             |  13 -
 airflow/_vendor/__init__.py                        |  18 -
 airflow/_vendor/nvd3/LICENSE                       |  24 -
 airflow/_vendor/nvd3/NVD3Chart.py                  | 505 ---------------------
 airflow/_vendor/nvd3/__init__.py                   |  29 --
 airflow/_vendor/nvd3/cumulativeLineChart.py        | 104 -----
 airflow/_vendor/nvd3/discreteBarChart.py           |  91 ----
 airflow/_vendor/nvd3/ipynb.py                      |  91 ----
 airflow/_vendor/nvd3/lineChart.py                  | 120 -----
 airflow/_vendor/nvd3/linePlusBarChart.py           | 131 ------
 airflow/_vendor/nvd3/lineWithFocusChart.py         | 105 -----
 airflow/_vendor/nvd3/multiBarChart.py              |  95 ----
 airflow/_vendor/nvd3/multiBarHorizontalChart.py    | 100 ----
 airflow/_vendor/nvd3/pieChart.py                   | 101 -----
 airflow/_vendor/nvd3/scatterChart.py               | 121 -----
 airflow/_vendor/nvd3/stackedAreaChart.py           |  99 ----
 airflow/_vendor/nvd3/templates/base.html           |  35 --
 airflow/_vendor/nvd3/templates/content.html        | 123 -----
 .../nvd3/templates/cumulativelinechart.html        |  10 -
 .../_vendor/nvd3/templates/discretebarchart.html   |  31 --
 .../_vendor/nvd3/templates/linebarwfocuschart.html |  60 ---
 airflow/_vendor/nvd3/templates/linechart.html      |  46 --
 .../_vendor/nvd3/templates/lineplusbarchart.html   |  43 --
 .../_vendor/nvd3/templates/linewfocuschart.html    |  10 -
 airflow/_vendor/nvd3/templates/multibarchart.html  |  10 -
 .../nvd3/templates/multibarcharthorizontal.html    |  10 -
 airflow/_vendor/nvd3/templates/page.html           |  12 -
 airflow/_vendor/nvd3/templates/piechart.html       |  80 ----
 airflow/_vendor/nvd3/templates/scatterchart.html   |  52 ---
 .../_vendor/nvd3/templates/stackedareachart.html   |   7 -
 airflow/_vendor/nvd3/translator.py                 |  71 ---
 airflow/_vendor/slugify/LICENSE                    |  21 -
 airflow/_vendor/slugify/__init__.py                |   6 -
 airflow/_vendor/slugify/slugify.py                 | 183 --------
 airflow/www/views.py                               |   2 +-
 requirements/requirements-python3.6.txt            |   4 +-
 requirements/requirements-python3.7.txt            |   8 +-
 requirements/setup-3.6.md5                         |   2 +-
 requirements/setup-3.7.md5                         |   2 +-
 scripts/ci/in_container/_in_container_utils.sh     |   1 -
 scripts/ci/in_container/run_pylint_main.sh         |   1 -
 setup.cfg                                          |   5 +-
 setup.py                                           |   3 +-
 49 files changed, 30 insertions(+), 2594 deletions(-)

diff --git a/.coveragerc b/.coveragerc
index 9a07159..8380515 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -24,4 +24,3 @@ omit =
     airflow/migrations/*
     airflow/www/node_modules/**
     airflow/www_rbac/node_modules/**
-    airflow/_vendor/*
diff --git a/.flake8 b/.flake8
index f1bf203..f9bf91e 100644
--- a/.flake8
+++ b/.flake8
@@ -1,7 +1,7 @@
 [flake8]
 max-line-length = 110
 ignore = E731,W504,I001,W503
-exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,.eggs,*.egg,*/_vendor/*,node_modules
+exclude = .svn,CVS,.bzr,.hg,.git,__pycache__,.eggs,*.egg,node_modules
 format = ${cyan}%(path)s${reset}:${yellow_bold}%(row)d${reset}:${green_bold}%(col)d${reset}: ${red_bold}%(code)s${reset} %(text)s
 per-file-ignores =
     airflow/models/__init__.py:F401
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 9f6f7a7..baa48a3 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -25,11 +25,11 @@ repos:
     rev: v1.1.7
     hooks:
       - id: forbid-tabs
-        exclude: ^airflow/_vendor/.*$|^docs/Makefile$
+        exclude: ^docs/Makefile$
       - id: insert-license
         name: Add license for all SQL files
         files: \.sql$
-        exclude: ^\.github/.*$|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         args:
           - --comment-style
           - "/*||*/"
@@ -38,7 +38,7 @@ repos:
           - --fuzzy-match-generates-todo
       - id: insert-license
         name: Add license for all other files
-        exclude: ^\.github/.*$"|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         args:
           - --comment-style
           - "|#|"
@@ -49,7 +49,7 @@ repos:
           \.properties$|\.cfg$|\.conf$|\.ini$|\.ldif$|\.readthedocs$|\.service$|^Dockerfile.*$
       - id: insert-license
         name: Add license for all rst files
-        exclude: ^\.github/.*$"|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         args:
           - --comment-style
           - "||"
@@ -60,7 +60,7 @@ repos:
       - id: insert-license
         name: Add license for all JS/CSS files
         files: \.(js|css)$
-        exclude: ^\.github/.*$|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         args:
           - --comment-style
           - "/**| *| */"
@@ -71,7 +71,7 @@ repos:
         name: Add license for all JINJA template files
         files: "^airflow/www/templates/.*\\.html$|^docs/templates/.*\\.html$|^airflow/contrib/plugins/\
 metastore_browser/templates/.*\\.html$|.*\\.jinja2"
-        exclude: ^\.github/.*$|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         args:
           - --comment-style
           - "{#||#}"
@@ -80,7 +80,7 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
           - --fuzzy-match-generates-todo
       - id: insert-license
         name: Add license for all shell files
-        exclude: ^\.github/.*$"|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         files: ^breeze$|^breeze-complete$|\.sh$|\.bash$|\.bats$
         args:
           - --comment-style
@@ -90,7 +90,7 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
           - --fuzzy-match-generates-todo
       - id: insert-license
         name: Add license for all python files
-        exclude: ^\.github/.*$"|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         types: [python]
         args:
           - --comment-style
@@ -100,7 +100,7 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
           - --fuzzy-match-generates-todo
       - id: insert-license
         name: Add license for all XML files
-        exclude: ^\.github/.*$"|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         types: [xml]
         args:
           - --comment-style
@@ -110,7 +110,7 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
           - --fuzzy-match-generates-todo
       - id: insert-license
         name: Add license for all yaml files
-        exclude: ^\.github/.*$"|^airflow/_vendor/.*$
+        exclude: ^\.github/.*$
         types: [yaml]
         args:
           - --comment-style
@@ -121,7 +121,7 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
       - id: insert-license
         name: Add license for all md files
         files: \.md$
-        exclude: ^\.github/.*$|^airflow/_vendor/.*|PROVIDERS_CHANGES.*\.md
+        exclude: ^\.github/.*$|PROVIDERS_CHANGES.*\.md
         args:
           - --comment-style
           - "<!--|| -->"
@@ -154,7 +154,6 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
       - id: fix-encoding-pragma
         args:
           - --remove
-        exclude: ^airflow/_vendor/.*$
   - repo: https://github.com/pre-commit/pygrep-hooks
     rev: v1.5.1
     hooks:
@@ -174,7 +173,6 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
         language: docker_image
         entry: koalaman/shellcheck:stable -x -a
         files: ^breeze$|^breeze-complete$|\.sh$|^hooks/build$|^hooks/push$|\.bash$|\.bats$
-        exclude: ^airflow/_vendor/.*$
       - id: lint-openapi
         name: Lint OpenAPI using speccy
         language: docker_image
@@ -198,7 +196,7 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
         entry: isort
         files: \.py$
         # To keep consistent with the global isort skip config defined in setup.cfg
-        exclude: ^airflow/_vendor/.*$|^build/.*$|^.tox/.*$|^venv/.*$
+        exclude: ^build/.*$|^.tox/.*$|^venv/.*$
         additional_dependencies: ['isort']
       - id: setup-order
         name: Checks for an order of dependencies in setup.py
@@ -333,14 +331,14 @@ metastore_browser/templates/.*\\.html$|.*\\.jinja2"
         language: system
         entry: "./scripts/ci/pre_commit_mypy.sh"
         files: \.py$
-        exclude: ^airflow/_vendor/.*$|^dev|^backport_packages
+        exclude: ^dev|^backport_packages
         require_serial: true
       - id: pylint
         name: Run pylint for main sources
         language: system
         entry: "./scripts/ci/pre_commit_pylint_main.sh"
         files: \.py$
-        exclude: ^tests/.*\.py$|^airflow/_vendor/.*|^scripts/.*\.py$|^dev|^backport_packages|^kubernetes_tests
+        exclude: ^tests/.*\.py$|^scripts/.*\.py$|^dev|^backport_packages|^kubernetes_tests
         pass_filenames: true
         require_serial: true  # Pylint tests should be run in one chunk to detect all cycles
       - id: pylint-tests
diff --git a/.rat-excludes b/.rat-excludes
index 47e9eb6..4f798f1 100644
--- a/.rat-excludes
+++ b/.rat-excludes
@@ -77,9 +77,6 @@ apache-airflow-.*\+bin.tar.gz.*
 PULL_REQUEST_TEMPLATE.md
 PROVIDERS_CHANGES*.md
 
-# vendored modules
-_vendor/*
-
 # Temporary list of files to make compatible with Pylint
 pylint_todo.txt
 
diff --git a/LICENSE b/LICENSE
index 03539c2..78fd5a7 100644
--- a/LICENSE
+++ b/LICENSE
@@ -238,7 +238,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt.
     (MIT License) ElasticMock v1.3.2 (https://github.com/vrcmarcos/elasticmock)
     (MIT License) MomentJS v2.24.0 (http://momentjs.com/)
     (MIT License) moment-strftime v0.5.0 (https://github.com/benjaminoakes/moment-strftime)
-    (MIT License) python-slugify v2.0.1 (https://github.com/un33k/python-slugify)
+    (MIT License) python-slugify v4.0.0 (https://github.com/un33k/python-slugify)
     (MIT License) python-nvd3 v0.15.0 (https://github.com/areski/python-nvd3)
     (MIT License) eonasdan-bootstrap-datetimepicker v4.17.37 (https://github.com/eonasdan/bootstrap-datetimepicker/)
 
diff --git a/MANIFEST.in b/MANIFEST.in
index 67e50a3..e4c318c 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -24,7 +24,6 @@ graft licenses
 graft airflow/www
 graft airflow/www/static
 graft airflow/www/templates
-graft airflow/_vendor/
 include airflow/alembic.ini
 include airflow/git_version
 include airflow/serialization/schema.json
diff --git a/airflow/_vendor/README b/airflow/_vendor/README
deleted file mode 100644
index a79ea89..0000000
--- a/airflow/_vendor/README
+++ /dev/null
@@ -1,13 +0,0 @@
-Original files in this directory were created with the following commands::
-
-    mkdir -p slugify/
-    curl -fsSL -O https://files.pythonhosted.org/packages/1f/9c/8b07d625e9c9df567986d887f0375075abb1923e49d074a7803cd1527dae/python-slugify-2.0.1.tar.gz
-    tar -xzf python-slugify-*.tar.gz --strip-components=2 -C slugify/ '*/slugify/*'
-    tar -xzf python-slugify-*.tar.gz --strip-components=1 -C slugify/ '*/LICENSE'
-    rm *.tar.gz
-
-    mkdir -p nvd3/
-    curl -fsSL -O https://files.pythonhosted.org/packages/0b/aa/97165daa6e319409c5c2582e62736a7353bda3c90d90fdcb0b11e116dd2d/python-nvd3-0.15.0.tar.gz
-    tar -xzf python-nvd3-*.tar.gz --strip-components=2 -C nvd3/ '*/nvd3/*'
-    tar -xzf python-nvd3-*.tar.gz --strip-components=1 -C nvd3/ '*/LICENSE'
-    rm *.tar.gz
diff --git a/airflow/_vendor/__init__.py b/airflow/_vendor/__init__.py
deleted file mode 100644
index 114d189..0000000
--- a/airflow/_vendor/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
diff --git a/airflow/_vendor/nvd3/LICENSE b/airflow/_vendor/nvd3/LICENSE
deleted file mode 100644
index 1add624..0000000
--- a/airflow/_vendor/nvd3/LICENSE
+++ /dev/null
@@ -1,24 +0,0 @@
-The MIT License (MIT)
-
-Python-nvd3
-
-Copyright (c) 2013 Arezqui Belaid <ar...@gmail.com> and other contributors
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/airflow/_vendor/nvd3/NVD3Chart.py b/airflow/_vendor/nvd3/NVD3Chart.py
deleted file mode 100644
index c0608c9..0000000
--- a/airflow/_vendor/nvd3/NVD3Chart.py
+++ /dev/null
@@ -1,505 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from optparse import OptionParser
-from jinja2 import Environment, PackageLoader
-from airflow._vendor.slugify import slugify
-
-try:
-    import simplejson as json
-except ImportError:
-    import json
-
-CONTENT_FILENAME = "./content.html"
-PAGE_FILENAME = "./page.html"
-
-
-pl = PackageLoader('airflow._vendor.nvd3', 'templates')
-jinja2_env = Environment(lstrip_blocks=True, trim_blocks=True, loader=pl)
-
-template_content = jinja2_env.get_template(CONTENT_FILENAME)
-template_page = jinja2_env.get_template(PAGE_FILENAME)
-
-
-def stab(tab=1):
-    """
-    create space tabulation
-    """
-    return ' ' * 4 * tab
-
-
-class NVD3Chart(object):
-    """
-    NVD3Chart Base class.
-    """
-    #: chart count
-    count = 0
-    #:  directory holding the assets (bower_components)
-    assets_directory = './bower_components/'
-
-    # this attribute is overriden by children of this
-    # class
-    CHART_FILENAME = None
-    template_environment = Environment(lstrip_blocks=True, trim_blocks=True,
-                                       loader=pl)
-
-    def __init__(self, **kwargs):
-        """
-        This is the base class for all the charts. The following keywords are
-        accepted:
-
-        :keyword: **display_container** - default: ``True``
-        :keyword: **jquery_on_ready** - default: ``False``
-        :keyword: **charttooltip_dateformat** - default: ``'%d %b %Y'``
-        :keyword: **name** - default: the class name
-                    ``model`` - set the model (e.g. ``pieChart``, `
-                    ``LineWithFocusChart``, ``MultiBarChart``).
-        :keyword: **color_category** - default - ``None``
-        :keyword: **color_list** - default - ``None``
-                  used by pieChart (e.g. ``['red', 'blue', 'orange']``)
-        :keyword: **margin_bottom** - default - ``20``
-        :keyword: **margin_left** - default - ``60``
-        :keyword: **margin_right** - default - ``60``
-        :keyword: **margin_top** - default - ``30``
-        :keyword: **height** - default - ``''``
-        :keyword: **width** - default - ``''``
-        :keyword: **stacked** - default - ``False``
-        :keyword: **focus_enable** - default - ``False``
-        :keyword: **resize** - define - ``False``
-        :keyword: **show_legend** - default - ``True``
-        :keyword: **show_labels** - default - ``True``
-        :keyword: **tag_script_js** - default - ``True``
-        :keyword: **use_interactive_guideline** - default - ``False``
-        :keyword: **chart_attr** - default - ``None``
-        :keyword: **extras** - default - ``None``
-
-            Extra chart modifiers. Use this to modify different attributes of
-            the chart.
-        :keyword: **x_axis_date** - default - False
-            Signal that x axis is a date axis
-        :keyword: **date_format** - default - ``%x``
-                  see https://github.com/mbostock/d3/wiki/Time-Formatting
-        :keyword: **x_axis_format** - default - ``''``.
-        :keyword: **y_axis_format** - default - ``''``.
-        :keyword: **style** - default - ``''``
-            Style modifiers for the DIV container.
-        :keyword: **color_category** - default - ``category10``
-
-            Acceptable values are nvd3 categories such as
-            ``category10``, ``category20``, ``category20c``.
-        """
-        # set the model
-        self.model = self.__class__.__name__  #: The chart model,
-
-        #: an Instance of Jinja2 template
-        self.template_page_nvd3 = template_page
-        self.template_content_nvd3 = template_content
-        self.series = []
-        self.axislist = {}
-        # accepted keywords
-        self.display_container = kwargs.get('display_container', True)
-        self.charttooltip_dateformat = kwargs.get('charttooltip_dateformat',
-                                                  '%d %b %Y')
-        self._slugify_name(kwargs.get('name', self.model))
-        self.jquery_on_ready = kwargs.get('jquery_on_ready', False)
-        self.color_category = kwargs.get('color_category', None)
-        self.color_list = kwargs.get('color_list', None)
-        self.margin_bottom = kwargs.get('margin_bottom', 20)
-        self.margin_left = kwargs.get('margin_left', 60)
-        self.margin_right = kwargs.get('margin_right', 60)
-        self.margin_top = kwargs.get('margin_top', 30)
-        self.height = kwargs.get('height', '')
-        self.width = kwargs.get('width', '')
-        self.stacked = kwargs.get('stacked', False)
-        self.focus_enable = kwargs.get('focus_enable', False)
-        self.resize = kwargs.get('resize', False)
-        self.show_legend = kwargs.get('show_legend', True)
-        self.show_labels = kwargs.get('show_labels', True)
-        self.tag_script_js = kwargs.get('tag_script_js', True)
-        self.use_interactive_guideline = kwargs.get("use_interactive_guideline",
-                                                    False)
-        self.chart_attr = kwargs.get("chart_attr", {})
-        self.extras = kwargs.get('extras', None)
-        self.style = kwargs.get('style', '')
-        self.date_format = kwargs.get('date_format', '%x')
-        self.x_axis_date = kwargs.get('x_axis_date', False)
-        #: x-axis contain date format or not
-        # possible duplicate of x_axis_date
-        self.date_flag = kwargs.get('date_flag', False)
-        self.x_axis_format = kwargs.get('x_axis_format', '')
-        # Load remote JS assets or use the local bower assets?
-        self.remote_js_assets = kwargs.get('remote_js_assets', True)
-
-        # None keywords attribute that should be modified by methods
-        # We should change all these to _attr
-
-        self.htmlcontent = ''  #: written by buildhtml
-        self.htmlheader = ''
-        #: Place holder for the graph (the HTML div)
-        #: Written by ``buildcontainer``
-        self.container = ''
-        #: Header for javascript code
-        self.containerheader = ''
-        # CDN http://cdnjs.com/libraries/nvd3/ needs to make sure it's up to
-        # date
-        self.header_css = [
-            '<link href="%s" rel="stylesheet" />' % h for h in
-            (
-                'https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.css' if self.remote_js_assets else self.assets_directory + 'nvd3/src/nv.d3.css',
-            )
-        ]
-
-        self.header_js = [
-            '<script src="%s"></script>' % h for h in
-            (
-                'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js' if self.remote_js_assets else self.assets_directory + 'd3/d3.min.js',
-                'https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.js' if self.remote_js_assets else self.assets_directory + 'nvd3/nv.d3.min.js'
-            )
-        ]
-
-        #: Javascript code as string
-        self.jschart = None
-        self.custom_tooltip_flag = False
-        self.tooltip_condition_string = ''
-        self.charttooltip = ''
-        self.serie_no = 1
-
-    def _slugify_name(self, name):
-        """Slufigy name with underscore"""
-        self.name = slugify(name, separator='_')
-
-    def add_serie(self, y, x, name=None, extra=None, **kwargs):
-        """
-        add serie - Series are list of data that will be plotted
-        y {1, 2, 3, 4, 5} / x {1, 2, 3, 4, 5}
-
-        **Attributes**:
-
-            * ``name`` - set Serie name
-            * ``x`` - x-axis data
-            * ``y`` - y-axis data
-
-            kwargs:
-
-            * ``shape`` - for scatterChart, you can set different shapes
-                          (circle, triangle etc...)
-            * ``size`` - for scatterChart, you can set size of different shapes
-            * ``type`` - for multiChart, type should be bar
-            * ``bar`` - to display bars in Chart
-            * ``color_list`` - define list of colors which will be
-                               used by pieChart
-            * ``color`` - set axis color
-            * ``disabled`` -
-
-            extra:
-
-            * ``tooltip`` - set tooltip flag
-            * ``date_format`` - set date_format for tooltip if x-axis is in
-              date format
-
-        """
-        if not name:
-            name = "Serie %d" % (self.serie_no)
-
-        # For scatterChart shape & size fields are added in serie
-        if 'shape' in kwargs or 'size' in kwargs:
-            csize = kwargs.get('size', 1)
-            cshape = kwargs.get('shape', 'circle')
-
-            serie = [{
-                'x': x[i],
-                'y': j,
-                'shape': cshape,
-                'size': csize[i] if isinstance(csize, list) else csize
-            } for i, j in enumerate(y)]
-        else:
-            if self.model == 'pieChart':
-                serie = [{'label': x[i], 'value': y} for i, y in enumerate(y)]
-            else:
-                serie = [{'x': x[i], 'y': y} for i, y in enumerate(y)]
-
-        data_keyvalue = {'values': serie, 'key': name}
-
-        # multiChart
-        # Histogram type='bar' for the series
-        if 'type' in kwargs and kwargs['type']:
-            data_keyvalue['type'] = kwargs['type']
-
-        # Define on which Y axis the serie is related
-        # a chart can have 2 Y axis, left and right, by default only one Y Axis is used
-        if 'yaxis' in kwargs and kwargs['yaxis']:
-            data_keyvalue['yAxis'] = kwargs['yaxis']
-        else:
-            if self.model != 'pieChart':
-                data_keyvalue['yAxis'] = '1'
-
-        if 'bar' in kwargs and kwargs['bar']:
-            data_keyvalue['bar'] = 'true'
-
-        if 'disabled' in kwargs and kwargs['disabled']:
-            data_keyvalue['disabled'] = 'true'
-
-        if 'color' in kwargs and kwargs['color']:
-            data_keyvalue['color'] = kwargs['color']
-
-        if extra:
-            if self.model == 'pieChart':
-                if 'color_list' in extra and extra['color_list']:
-                    self.color_list = extra['color_list']
-
-            if extra.get('date_format'):
-                self.charttooltip_dateformat = extra['date_format']
-
-            if extra.get('tooltip'):
-                self.custom_tooltip_flag = True
-
-                if self.model != 'pieChart':
-                    _start = extra['tooltip']['y_start']
-                    _end = extra['tooltip']['y_end']
-                    _start = ("'" + str(_start) + "' + ") if _start else ''
-                    _end = (" + '" + str(_end) + "'") if _end else ''
-
-                    if self.model == 'linePlusBarChart':
-                        if self.tooltip_condition_string:
-                            self.tooltip_condition_string += stab(5)
-                        self.tooltip_condition_string += stab(0) + "if(key.indexOf('" + name + "') > -1 ){\n" +\
-                            stab(6) + "var y = " + _start + " String(graph.point.y) " + _end + ";\n" +\
-                            stab(5) + "}\n"
-                    elif self.model == 'cumulativeLineChart':
-                        self.tooltip_condition_string += stab(0) + "if(key == '" + name + "'){\n" +\
-                            stab(6) + "var y = " + _start + " String(e) " + _end + ";\n" +\
-                            stab(5) + "}\n"
-                    else:
-                        self.tooltip_condition_string += stab(5) + "if(key == '" + name + "'){\n" +\
-                            stab(6) + "var y = " + _start + " String(graph.point.y) " + _end + ";\n" +\
-                            stab(5) + "}\n"
-
-                if self.model == 'pieChart':
-                    _start = extra['tooltip']['y_start']
-                    _end = extra['tooltip']['y_end']
-                    _start = ("'" + str(_start) + "' + ") if _start else ''
-                    _end = (" + '" + str(_end) + "'") if _end else ''
-                    self.tooltip_condition_string += "var y = " + _start + " String(y) " + _end + ";\n"
-
-        # Increment series counter & append
-        self.serie_no += 1
-        self.series.append(data_keyvalue)
-
-    def add_chart_extras(self, extras):
-        """
-        Use this method to add extra d3 properties to your chart.
-        For example, you want to change the text color of the graph::
-
-            chart = pieChart(name='pieChart', color_category='category20c', height=400, width=400)
-
-            xdata = ["Orange", "Banana", "Pear", "Kiwi", "Apple", "Strawberry", "Pineapple"]
-            ydata = [3, 4, 0, 1, 5, 7, 3]
-
-            extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}}
-            chart.add_serie(y=ydata, x=xdata, extra=extra_serie)
-
-        The above code will create graph with a black text, the following will change it::
-
-            text_white="d3.selectAll('#pieChart text').style('fill', 'white');"
-            chart.add_chart_extras(text_white)
-
-        The above extras will be appended to the java script generated.
-
-        Alternatively, you can use the following initialization::
-
-            chart = pieChart(name='pieChart',
-                             color_category='category20c',
-                             height=400, width=400,
-                             extras=text_white)
-        """
-        self.extras = extras
-
-    def set_graph_height(self, height):
-        """Set Graph height"""
-        self.height = str(height)
-
-    def set_graph_width(self, width):
-        """Set Graph width"""
-        self.width = str(width)
-
-    def set_containerheader(self, containerheader):
-        """Set containerheader"""
-        self.containerheader = containerheader
-
-    def set_date_flag(self, date_flag=False):
-        """Set date flag"""
-        self.date_flag = date_flag
-
-    def set_custom_tooltip_flag(self, custom_tooltip_flag):
-        """Set custom_tooltip_flag & date_flag"""
-        self.custom_tooltip_flag = custom_tooltip_flag
-
-    def __str__(self):
-        """return htmlcontent"""
-        self.buildhtml()
-        return self.htmlcontent
-
-    def buildcontent(self):
-        """Build HTML content only, no header or body tags. To be useful this
-        will usually require the attribute `juqery_on_ready` to be set which
-        will wrap the js in $(function(){<regular_js>};)
-        """
-        self.buildcontainer()
-        # if the subclass has a method buildjs this method will be
-        # called instead of the method defined here
-        # when this subclass method is entered it does call
-        # the method buildjschart defined here
-        self.buildjschart()
-        self.htmlcontent = self.template_content_nvd3.render(chart=self)
-
-    def buildhtml(self):
-        """Build the HTML page
-        Create the htmlheader with css / js
-        Create html page
-        Add Js code for nvd3
-        """
-        self.buildcontent()
-        self.content = self.htmlcontent
-        self.htmlcontent = self.template_page_nvd3.render(chart=self)
-
-    # this is used by django-nvd3
-    def buildhtmlheader(self):
-        """generate HTML header content"""
-        self.htmlheader = ''
-        # If the JavaScript assets have already been injected, don't bother re-sourcing them.
-        global _js_initialized
-        if '_js_initialized' not in globals() or not _js_initialized:
-            for css in self.header_css:
-                self.htmlheader += css
-            for js in self.header_js:
-                self.htmlheader += js
-
-    def buildcontainer(self):
-        """generate HTML div"""
-        if self.container:
-            return
-
-        # Create SVG div with style
-        if self.width:
-            if self.width[-1] != '%':
-                self.style += 'width:%spx;' % self.width
-            else:
-                self.style += 'width:%s;' % self.width
-        if self.height:
-            if self.height[-1] != '%':
-                self.style += 'height:%spx;' % self.height
-            else:
-                self.style += 'height:%s;' % self.height
-        if self.style:
-            self.style = 'style="%s"' % self.style
-
-        self.container = self.containerheader + \
-            '<div id="%s"><svg %s></svg></div>\n' % (self.name, self.style)
-
-    def buildjschart(self):
-        """generate javascript code for the chart"""
-        self.jschart = ''
-
-        # add custom tooltip string in jschart
-        # default condition (if build_custom_tooltip is not called explicitly with date_flag=True)
-        if self.tooltip_condition_string == '':
-            self.tooltip_condition_string = 'var y = String(graph.point.y);\n'
-
-        # Include data
-        self.series_js = json.dumps(self.series)
-
-    def create_x_axis(self, name, label=None, format=None, date=False, custom_format=False):
-        """Create X-axis"""
-        axis = {}
-        if custom_format and format:
-            axis['tickFormat'] = format
-        elif format:
-            if format == 'AM_PM':
-                axis['tickFormat'] = "function(d) { return get_am_pm(parseInt(d)); }"
-            else:
-                axis['tickFormat'] = "d3.format(',%s')" % format
-
-        if label:
-            axis['axisLabel'] = "'" + label + "'"
-
-        # date format : see https://github.com/mbostock/d3/wiki/Time-Formatting
-        if date:
-            self.dateformat = format
-            axis['tickFormat'] = ("function(d) { return d3.time.format('%s')"
-                                  "(new Date(parseInt(d))) }\n"
-                                  "" % self.dateformat)
-            # flag is the x Axis is a date
-            if name[0] == 'x':
-                self.x_axis_date = True
-
-        # Add new axis to list of axis
-        self.axislist[name] = axis
-
-        # Create x2Axis if focus_enable
-        if name == "xAxis" and self.focus_enable:
-            self.axislist['x2Axis'] = axis
-
-    def create_y_axis(self, name, label=None, format=None, custom_format=False):
-        """
-        Create Y-axis
-        """
-        axis = {}
-
-        if custom_format and format:
-            axis['tickFormat'] = format
-        elif format:
-            axis['tickFormat'] = "d3.format(',%s')" % format
-
-        if label:
-            axis['axisLabel'] = "'" + label + "'"
-
-        # Add new axis to list of axis
-        self.axislist[name] = axis
-
-
-class TemplateMixin(object):
-    """
-    A mixin that override buildcontent. Instead of building the complex
-    content template we exploit Jinja2 inheritance. Thus each chart class
-    renders it's own chart template which inherits from content.html
-    """
-    def buildcontent(self):
-        """Build HTML content only, no header or body tags. To be useful this
-        will usually require the attribute `juqery_on_ready` to be set which
-        will wrap the js in $(function(){<regular_js>};)
-        """
-        self.buildcontainer()
-        # if the subclass has a method buildjs this method will be
-        # called instead of the method defined here
-        # when this subclass method is entered it does call
-        # the method buildjschart defined here
-        self.buildjschart()
-        self.htmlcontent = self.template_chart_nvd3.render(chart=self)
-
-
-def _main():
-    """
-    Parse options and process commands
-    """
-    # Parse arguments
-    usage = "usage: nvd3.py [options]"
-    parser = OptionParser(usage=usage,
-                          version=("python-nvd3 - Charts generator with "
-                                   "nvd3.js and d3.js"))
-    parser.add_option("-q", "--quiet",
-                      action="store_false", dest="verbose", default=True,
-                      help="don't print messages to stdout")
-
-    (options, args) = parser.parse_args()
-
-
-if __name__ == '__main__':
-    _main()
diff --git a/airflow/_vendor/nvd3/__init__.py b/airflow/_vendor/nvd3/__init__.py
deleted file mode 100755
index 5b737b4..0000000
--- a/airflow/_vendor/nvd3/__init__.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-__version__ = '0.15.0'
-__all__ = ['lineChart', 'pieChart', 'lineWithFocusChart',
-           'stackedAreaChart', 'multiBarHorizontalChart',
-           'linePlusBarChart', 'cumulativeLineChart',
-           'scatterChart', 'discreteBarChart', 'multiBarChart']
-
-
-from .lineChart import lineChart
-from .pieChart import pieChart
-from .lineWithFocusChart import lineWithFocusChart
-from .stackedAreaChart import stackedAreaChart
-from .multiBarHorizontalChart import multiBarHorizontalChart
-from .linePlusBarChart import linePlusBarChart
-from .cumulativeLineChart import cumulativeLineChart
-from .scatterChart import scatterChart
-from .discreteBarChart import discreteBarChart
-from .multiBarChart import multiBarChart
-from . import ipynb
diff --git a/airflow/_vendor/nvd3/cumulativeLineChart.py b/airflow/_vendor/nvd3/cumulativeLineChart.py
deleted file mode 100644
index 6908c3a..0000000
--- a/airflow/_vendor/nvd3/cumulativeLineChart.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class cumulativeLineChart(TemplateMixin, NVD3Chart):
-    """
-    A cumulative line chart is used when you have one important grouping representing
-    an ordered set of data and one value to show, summed over time.
-
-    Python example::
-
-        from nvd3 import cumulativeLineChart
-        chart = cumulativeLineChart(name='cumulativeLineChart', x_is_date=True)
-        xdata = [1365026400000000, 1365026500000000, 1365026600000000]
-        ydata = [6, 5, 1]
-        y2data = [36, 55, 11]
-
-        extra_serie = {"tooltip": {"y_start": "There are ", "y_end": " calls"}}
-        chart.add_serie(name="Serie 1", y=ydata, x=xdata, extra=extra_serie)
-
-        extra_serie = {"tooltip": {"y_start": "", "y_end": " mins"}}
-        chart.add_serie(name="Serie 2", y=y2data, x=xdata, extra=extra_serie)
-        chart.buildhtml()
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="cumulativeLineChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-            data_cumulativeLineChart=[{"values": [{"y": 6, "x": 1365026400000000},
-            {"y": 5, "x": 1365026500000000},
-            {"y": 1, "x": 1365026600000000}],
-            "key": "Serie 1", "yAxis": "1"},
-            {"values": [{"y": 36, "x": 1365026400000000},
-            {"y": 55, "x": 1365026500000000},
-            {"y": 11, "x": 1365026600000000}], "key": "Serie 2", "yAxis": "1"}];
-            nv.addGraph(function() {
-                var chart = nv.models.cumulativeLineChart();
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-                var datum = data_cumulativeLineChart;
-
-                        chart.xAxis
-                            .tickFormat(function(d) { return d3.time.format('%d %b %Y')(new Date(parseInt(d))) });
-                        chart.yAxis
-                            .tickFormat(d3.format(',.1%'));
-
-                    chart.tooltipContent(function(key, y, e, graph) {
-                        var x = d3.time.format("%d %b %Y")(new Date(parseInt(graph.point.x)));
-                        var y = String(graph.point.y);
-                        if(key == 'Serie 1'){
-                                var y = 'There are ' +  String(e)  + ' calls';
-                            }if(key == 'Serie 2'){
-                                var y =  String(e)  + ' mins';
-                            }
-                        tooltip_str = '<center><b>'+key+'</b></center>' + y + ' on ' + x;
-                        return tooltip_str;
-                    });
-                    chart.showLegend(true);
-
-                d3.select('#cumulativeLineChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('height', 450)
-                    .call(chart); });
-        </script>
-
-    """
-
-    CHART_FILENAME = "./cumulativelinechart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-        self.model = 'cumulativeLineChart'
-
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-
-        if kwargs.get('x_is_date', False):
-            self.set_date_flag(True)
-            self.create_x_axis('xAxis',
-                               format=kwargs.get('x_axis_format', '%d %b %Y'),
-                               date=True)
-            self.set_custom_tooltip_flag(True)
-        else:
-            self.create_x_axis('xAxis', format=kwargs.get(
-                'x_axis_format', '.2f'))
-
-        self.create_y_axis('yAxis', format=kwargs.get('y_axis_format', '.1%'))
-
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/discreteBarChart.py b/airflow/_vendor/nvd3/discreteBarChart.py
deleted file mode 100644
index e267ce0..0000000
--- a/airflow/_vendor/nvd3/discreteBarChart.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class discreteBarChart(TemplateMixin, NVD3Chart):
-    """
-    A discrete bar chart or bar graph is a chart with rectangular bars with
-    lengths proportional to the values that they represent.
-
-    Python example::
-
-        from nvd3 import discreteBarChart
-        chart = discreteBarChart(name='discreteBarChart', height=400, width=400)
-
-        xdata = ["A", "B", "C", "D", "E", "F"]
-        ydata = [3, 4, 0, -3, 5, 7]
-
-        chart.add_serie(y=ydata, x=xdata)
-        chart.buildhtml()
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="discreteBarChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-            data_discreteBarChart=[{"values": [{"y": 3, "x": "A"}, {"y": 4, "x": "B"}, {"y": 0, "x": "C"}, {"y": -3, "x": "D"}, {"y": 5, "x": "E"}, {"y": 7, "x": "F"}], "key": "Serie 1", "yAxis": "1"}];
-
-            nv.addGraph(function() {
-                var chart = nv.models.discreteBarChart();
-
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-
-                var datum = data_discreteBarChart;
-                        chart.yAxis
-                            .tickFormat(d3.format(',.0f'));
-                        chart.tooltipContent(function(key, y, e, graph) {
-                            var x = String(graph.point.x);
-                            var y = String(graph.point.y);
-                            var y = String(graph.point.y);
-
-                            tooltip_str = '<center><b>'+key+'</b></center>' + y + ' at ' + x;
-                            return tooltip_str;
-                        });
-
-                d3.select('#discreteBarChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('width', 400)
-                    .attr('height', 400)
-                    .call(chart);
-            });
-        </script>
-
-
-    """
-    CHART_FILENAME = "./discretebarchart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-        self.model = 'discreteBarChart'
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-
-        if kwargs.get('x_is_date', False):
-            self.set_date_flag(True)
-            self.create_x_axis('xAxis',
-                               format=kwargs.get('x_axis_format',
-                                                 "%d %b %Y %H %S"),
-                               date=True)
-        else:
-            self.create_x_axis('xAxis', format=None)
-
-        self.create_y_axis('yAxis', format=kwargs.get('y_axis_format', ".0f"))
-
-        self.set_custom_tooltip_flag(True)
-
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/ipynb.py b/airflow/_vendor/nvd3/ipynb.py
deleted file mode 100644
index f421afc..0000000
--- a/airflow/_vendor/nvd3/ipynb.py
+++ /dev/null
@@ -1,91 +0,0 @@
-'''
-ipython compatability module for nvd3-python
-This adds simple ipython compatibility to the nvd3-python package, without making any
-major modifications to how the main package is structured.  It utilizes the IPython
-display-formatter functionality, as described at:
-http://nbviewer.ipython.org/github/ipython/ipython/blob/master/examples/notebooks/Custom%20Display%20Logic.ipynb
-For additional examples, see:
-https://github.com/sympy/sympy/blob/master/sympy/interactive/printing.py
-'''
-
-try:
-    _ip = get_ipython()
-except:
-    _ip = None
-if _ip and _ip.__module__.lower().startswith('ipy'):
-    global _js_initialized
-    _js_initialized = False
-
-    def _print_html(chart):
-        '''Function to return the HTML code for the div container plus the javascript
-        to generate the chart.  This function is bound to the ipython formatter so that
-        charts are displayed inline.'''
-        global _js_initialized
-        if not _js_initialized:
-            print('js not initialized - pausing to allow time for it to load...')
-            initialize_javascript()
-            import time
-            time.sleep(5)
-        chart.buildhtml()
-        return chart.htmlcontent
-
-    def _setup_ipython_formatter(ip):
-        ''' Set up the ipython formatter to display HTML formatted output inline'''
-        from IPython import __version__ as IPython_version
-        from nvd3 import __all__ as nvd3_all
-
-        if IPython_version >= '0.11':
-            html_formatter = ip.display_formatter.formatters['text/html']
-            for chart_type in nvd3_all:
-                html_formatter.for_type_by_name('nvd3.' + chart_type, chart_type, _print_html)
-
-    def initialize_javascript(d3_js_url='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js',
-                              nvd3_js_url='https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.js',
-                              nvd3_css_url='https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.css',
-                              use_remote=False):
-        '''Initialize the ipython notebook to be able to display nvd3 results.
-        by instructing IPython to load the nvd3 JS and css files, and the d3 JS file.
-
-        by default, it looks for the files in your IPython Notebook working directory.
-
-        Takes the following options:
-
-        use_remote: use remote hosts for d3.js, nvd3.js, and nv.d3.css (default False)
-        * Note:  the following options are ignored if use_remote is False:
-        nvd3_css_url: location of nvd3 css file (default https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.css)
-        nvd3_js_url: location of nvd3 javascript file (default  https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.css)
-        d3_js_url: location of d3 javascript file (default https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js)
-        '''
-        from IPython.display import display, Javascript, HTML
-
-        if not use_remote:
-            # these file locations are for IPython 1.x, and will probably change when 2.x is released
-            d3_js_url = 'files/d3.v3.js'
-            nvd3_js_url = 'files/nv.d3.js'
-            nvd3_css_url = 'files/nv.d3.css'
-
-        # load the required javascript files
-
-        #display(Javascript('''$.getScript("%s")''' %(d3_js_url)))
-        display(HTML('''<link media="all" href="%s" type="text/css"
-                        rel="stylesheet"/>''' % (nvd3_css_url)))
-        # The following two methods for loading the script file are redundant.
-        # This is intentional.
-        # Ipython's loading of javscript in version 1.x is a bit squirrely, especially
-        # when creating demos to view in nbviewer.
-        # by trying twice, in two different ways (one using jquery and one using plain old
-        # HTML), we maximize our chances of successfully loading the script.
-        display(Javascript('''$.getScript("%s")''' % (nvd3_js_url)))
-        display(Javascript('''$.getScript("%s", function() {
-                              $.getScript("%s", function() {})});''' % (d3_js_url, nvd3_js_url)))
-        display(HTML('<script src="%s"></script>' % (d3_js_url)))
-        display(HTML('<script src="%s"></script>' % (nvd3_js_url)))
-
-        global _js_initialized
-        _js_initialized = True
-
-    print('loaded nvd3 IPython extension\n'
-          'run nvd3.ipynb.initialize_javascript() to set up the notebook\n'
-          'help(nvd3.ipynb.initialize_javascript) for options')
-
-    _setup_ipython_formatter(_ip)
diff --git a/airflow/_vendor/nvd3/lineChart.py b/airflow/_vendor/nvd3/lineChart.py
deleted file mode 100644
index 3c1d415..0000000
--- a/airflow/_vendor/nvd3/lineChart.py
+++ /dev/null
@@ -1,120 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class lineChart(TemplateMixin, NVD3Chart):
-
-    """
-    A line chart or line graph is a type of chart which displays information
-    as a series of data points connected by straight line segments.
-
-    Python example::
-
-        from nvd3 import lineChart
-        chart = lineChart(name="lineChart", x_is_date=False, x_axis_format="AM_PM")
-
-        xdata = range(24)
-        ydata = [0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 4, 3, 3, 5, 7, 5, 3, 16, 6, 9, 15, 4, 12]
-        ydata2 = [9, 8, 11, 8, 3, 7, 10, 8, 6, 6, 9, 6, 5, 4, 3, 10, 0, 6, 3, 1, 0, 0, 0, 1]
-
-        extra_serie = {"tooltip": {"y_start": "There are ", "y_end": " calls"}}
-        chart.add_serie(y=ydata, x=xdata, name='sine', extra=extra_serie, **kwargs1)
-        extra_serie = {"tooltip": {"y_start": "", "y_end": " min"}}
-        chart.add_serie(y=ydata2, x=xdata, name='cose', extra=extra_serie, **kwargs2)
-        chart.buildhtml()
-
-    Javascript renderd to:
-
-    .. raw:: html
-
-        <div id="lineChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-
-            data_lineChart=[{"values": [{"y": 0, "x": 0}, {"y": 0, "x": 1}, {"y": 1, "x": 2}, {"y": 1, "x": 3}, {"y": 0, "x": 4}, {"y": 0, "x": 5}, {"y": 0, "x": 6}, {"y": 0, "x": 7}, {"y": 1, "x": 8}, {"y": 0, "x": 9}, {"y": 0, "x": 10}, {"y": 4, "x": 11}, {"y": 3, "x": 12}, {"y": 3, "x": 13}, {"y": 5, "x": 14}, {"y": 7, "x": 15}, {"y": 5, "x": 16}, {"y": 3, "x": 17}, {"y": 16, "x": 18}, {"y": 6, "x": 19}, {"y": 9, "x": 20}, {"y": 15, "x": 21}, {"y": 4, "x": 22}, {"y": 12, "x": 23}], "k [...]
-
-            nv.addGraph(function() {
-                var chart = nv.models.lineChart();
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-                var datum = data_lineChart;
-                        chart.xAxis
-                            .tickFormat(function(d) { return get_am_pm(parseInt(d)); });
-                        chart.yAxis
-                            .tickFormat(d3.format(',.02f'));
-
-                        chart.tooltipContent(function(key, y, e, graph) {
-                            var x = String(graph.point.x);
-                            var y = String(graph.point.y);
-                                                if(key == 'sine'){
-                                var y = 'There is ' +  String(graph.point.y)  + ' calls';
-                            }
-                            if(key == 'cose'){
-                                var y =  String(graph.point.y)  + ' min';
-                            }
-
-                            tooltip_str = '<center><b>'+key+'</b></center>' + y + ' at ' + x;
-                            return tooltip_str;
-                        });
-                    chart.showLegend(true);
-                        function get_am_pm(d){
-                    if (d > 12) {
-                        d = d - 12; return (String(d) + 'PM');
-                    }
-                    else {
-                        return (String(d) + 'AM');
-                    }
-                };
-
-                d3.select('#lineChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('height', 200)
-                    .call(chart);
-            return chart;
-        });
-        </script>
-
-    See the source code of this page, to see the underlying javascript.
-    """
-    CHART_FILENAME = "./linechart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-        self.model = 'lineChart'
-
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-
-        if kwargs.get('x_is_date', False):
-            self.set_date_flag(True)
-            self.create_x_axis('xAxis',
-                               format=kwargs.get('x_axis_format', '%d %b %Y'),
-                               date=True)
-            self.set_custom_tooltip_flag(True)
-        else:
-            if kwargs.get('x_axis_format') == 'AM_PM':
-                self.x_axis_format = format = 'AM_PM'
-            else:
-                format = kwargs.get('x_axis_format', 'r')
-            self.create_x_axis('xAxis', format=format,
-                               custom_format=kwargs.get('x_custom_format',
-                                                        False))
-        self.create_y_axis(
-            'yAxis',
-            format=kwargs.get('y_axis_format', '.02f'),
-            custom_format=kwargs.get('y_custom_format', False))
-
-        # must have a specified height, otherwise it superimposes both chars
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/linePlusBarChart.py b/airflow/_vendor/nvd3/linePlusBarChart.py
deleted file mode 100644
index 155a3f3..0000000
--- a/airflow/_vendor/nvd3/linePlusBarChart.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class linePlusBarChart(TemplateMixin, NVD3Chart):
-
-    """
-    A linePlusBarChart Chart is a type of chart which displays information
-    as a series of data points connected by straight line segments
-    and with some series with rectangular bars with lengths proportional
-    to the values that they represent.
-
-    Python example::
-
-        from nvd3 import linePlusBarChart
-        chart = linePlusBarChart(name="linePlusBarChart",
-                             width=500, height=400, x_axis_format="%d %b %Y",
-                             x_is_date=True, focus_enable=True,
-                             yaxis2_format="function(d) { return d3.format(',0.3f')(d) }")
-
-        xdata = [1338501600000, 1345501600000, 1353501600000]
-        ydata = [6, 5, 1]
-        y2data = [0.002, 0.003, 0.004]
-
-        extra_serie = {"tooltip": {"y_start": "There are ", "y_end": " calls"},
-                       "date_format": "%d %b %Y %H:%S" }
-        chart.add_serie(name="Serie 1", y=ydata, x=xdata, extra=extra_serie,
-                        bar=True)
-
-        extra_serie = {"tooltip": {"y_start": "There are ", "y_end": " min"}}
-        chart.add_serie(name="Serie 2", y=y2data, x=xdata, extra=extra_serie)
-        chart.buildcontent()
-
-    Note that in case you have two data serie with extreme different numbers,
-    that you would like to format in different ways,
-    you can pass a keyword *yaxis1_format* or *yaxis2_format* when
-    creating the graph.
-
-    In the example above the graph created presents the values of the second
-    data series with three digits right  of the decimal point.
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="linePlusBarChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-            data_linePlusBarChart=[{"bar": "true", "values": [{"y": 6, "x": 1338501600000}, {"y": 5, "x": 1345501600000}, {"y": 1, "x": 1353501600000}], "key": "Serie 1", "yAxis": "1"}, {"values": [{"y": 0.002, "x": 1338501600000}, {"y": 0.003, "x": 1345501600000}, {"y": 0.004, "x": 1353501600000}], "key": "Serie 2", "yAxis": "1"}];
-            nv.addGraph(function() {
-                var chart = nv.models.linePlusBarChart();
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-                var datum = data_linePlusBarChart;
-
-                    chart.y2Axis
-                        .tickFormat(function(d) { return d3.format(',0.3f')(d) });
-                    chart.xAxis
-                        .tickFormat(function(d) { return d3.time.format('%d %b %Y')(new Date(parseInt(d))) });
-                    chart.y1Axis
-                        .tickFormat(function(d) { return d3.format(',f')(d) });
-
-                    chart.tooltipContent(function(key, y, e, graph) {
-                        var x = d3.time.format("%d %b %Y %H:%S")(new Date(parseInt(graph.point.x)));
-                        var y = String(graph.point.y);
-                        if(key.indexOf('Serie 1') > -1 ){
-                                var y = 'There are ' +  String(graph.point.y)  + ' calls';
-                            }
-                            if(key.indexOf('Serie 2') > -1 ){
-                                var y = 'There are ' +  String(graph.point.y)  + ' min';
-                            }
-                        tooltip_str = '<center><b>'+key+'</b></center>' + y + ' on ' + x;
-                        return tooltip_str;
-                    });
-                    chart.showLegend(true);
-                d3.select('#linePlusBarChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('width', 500)
-                    .attr('height', 400)
-                    .call(chart);
-            });
-        </script>
-
-    """
-    CHART_FILENAME = "./lineplusbarchart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-        self.model = 'linePlusBarChart'
-
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-        self.yaxis1_format = kwargs.get('yaxis1_format',
-                                        "function(d) { return d3.format(',f')(d) }")
-        self.yaxis2_format = kwargs.get('yaxis2_format',
-                                        "function(d) { return d3.format(',f')(d) }")
-
-        if kwargs.get('x_is_date', False):
-            self.set_date_flag(True)
-            self.create_x_axis('xAxis',
-                               format=kwargs.get('x_axis_format',
-                                                 '%d %b %Y %H %S'),
-                               date=True)
-            self.create_x_axis('x2Axis', format=kwargs.get('x_axis_format',
-                                                           '%d %b %Y %H %S'),
-                               date=True)
-            self.set_custom_tooltip_flag(True)
-        else:
-            self.create_x_axis('xAxis', format=kwargs.get('x_axis_format',
-                                                          '.2f'))
-            self.create_x_axis('x2Axis', format=kwargs.get('x_axis_format',
-                                                           '.2f'))
-
-        self.create_y_axis('y1Axis', format=self.yaxis1_format,
-                           custom_format=True)
-        self.create_y_axis('y2Axis', format=self.yaxis2_format,
-                           custom_format=True)
-
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/lineWithFocusChart.py b/airflow/_vendor/nvd3/lineWithFocusChart.py
deleted file mode 100644
index d664df4..0000000
--- a/airflow/_vendor/nvd3/lineWithFocusChart.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class lineWithFocusChart(TemplateMixin, NVD3Chart):
-    """
-    A lineWithFocusChart or line graph is a type of chart which displays information
-    as a series of data points connected by straight line segments.
-    The lineWithFocusChart provide a smaller chart that act as a selector,
-    this is very useful if you want to zoom on a specific time period.
-
-    Python example::
-
-        from nvd3 import lineWithFocusChart
-        chart = lineWithFocusChart(name='lineWithFocusChart', x_is_date=True, x_axis_format="%d %b %Y")
-        xdata = [1365026400000000, 1365026500000000, 1365026600000000, 1365026700000000, 1365026800000000, 1365026900000000, 1365027000000000]
-        ydata = [-6, 5, -1, 2, 4, 8, 10]
-
-        extra_serie = {"tooltip": {"y_start": "", "y_end": " ext"},
-                       "date_format": "%d %b %Y"}
-        chart.add_serie(name="Serie 1", y=ydata, x=xdata, extra=extra_serie)
-        chart.buildhtml()
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="lineWithFocusChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-            data_lineWithFocusChart=[{"values": [{"y": -6, "x": 1365026400000000}, {"y": 5, "x": 1365026500000000}, {"y": -1, "x": 1365026600000000}], "key": "Serie 1", "yAxis": "1"}];
-            nv.addGraph(function() {
-                var chart = nv.models.lineWithFocusChart();
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-                var datum = data_lineWithFocusChart;
-                        chart.yAxis
-                            .tickFormat(d3.format(',.2f'));
-                        chart.y2Axis
-                            .tickFormat(d3.format(',.2f'));
-                        chart.xAxis
-                            .tickFormat(function(d) { return d3.time.format('%d %b %Y')(new Date(parseInt(d))) });
-                        chart.x2Axis
-                            .tickFormat(function(d) { return d3.time.format('%d %b %Y')(new Date(parseInt(d))) });
-
-                    chart.tooltipContent(function(key, y, e, graph) {
-                        var x = d3.time.format("%d %b %Y")(new Date(parseInt(graph.point.x)));
-                        var y = String(graph.point.y);
-                                            if(key == 'Serie 1'){
-                                var y =  String(graph.point.y)  + ' ext';
-                            }
-
-                        tooltip_str = '<center><b>'+key+'</b></center>' + y + ' on ' + x;
-                        return tooltip_str; });
-
-                    chart.showLegend(true);
-
-                d3.select('#lineWithFocusChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('height', 450)
-                    .call(chart); });
-        </script>
-
-    """
-
-    CHART_FILENAME = "./linewfocuschart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-        self.model = 'lineWithFocusChart'
-
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-
-        if kwargs.get('x_is_date', False):
-            self.set_date_flag(True)
-            self.create_x_axis('xAxis', format=kwargs.get('x_axis_format',
-                                                          '%d %b %Y %H %S'),
-                               date=True)
-            self.create_x_axis('x2Axis', format=kwargs.get('x_axis_format',
-                                                           '%d %b %Y %H %S'),
-                               date=True)
-            self.set_custom_tooltip_flag(True)
-        else:
-            self.create_x_axis('xAxis', format=kwargs.get('x_axis_format',
-                                                          '.2f'))
-            self.create_x_axis('x2Axis', format=kwargs.get('x_axis_format',
-                                                           '.2f'))
-
-        self.create_y_axis('yAxis', format=kwargs.get('y_axis_format', '.2f'))
-        self.create_y_axis('y2Axis', format=kwargs.get('y_axis_format', '.2f'))
-
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/multiBarChart.py b/airflow/_vendor/nvd3/multiBarChart.py
deleted file mode 100644
index 023e3e9..0000000
--- a/airflow/_vendor/nvd3/multiBarChart.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class multiBarChart(TemplateMixin, NVD3Chart):
-    """
-    A multiple bar graph contains comparisons of two or more categories or bars.
-    One axis represents a quantity and the other axis identifies a specific feature
-    about the categories. Reading a multiple bar graph includes looking at extremes
-    (tallest/longest vs. shortest) in each grouping.
-
-    Python example::
-
-        from nvd3 import multiBarChart
-        chart = multiBarChart(width=500, height=400, x_axis_format=None)
-        xdata = ['one', 'two', 'three', 'four']
-        ydata1 = [6, 12, 9, 16]
-        ydata2 = [8, 14, 7, 11]
-
-        chart.add_serie(name="Serie 1", y=ydata1, x=xdata)
-        chart.add_serie(name="Serie 2", y=ydata2, x=xdata)
-        chart.buildhtml()
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="multiBarChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-
-            data_multiBarChart=[{"values":
-                                [{"y": 6, "x": "one"},
-                                {"y": 12, "x": "two"},
-                                {"y": 9, "x": "three"},
-                                {"y": 16, "x": "four"}],
-                                "key": "Serie 1", "yAxis": "1"},
-                                {"values":
-                                    [{"y": 8, "x": "one"},
-                                    {"y": 14, "x": "two"},
-                                    {"y": 7, "x": "three"},
-                                    {"y": 11, "x": "four"}],
-                                "key": "Serie 2", "yAxis": "1"}];
-
-            nv.addGraph(function() {
-                var chart = nv.models.multiBarChart();
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-                var datum = data_multiBarChart;
-                        chart.yAxis
-                            .tickFormat(d3.format(',.2f'));
-                    chart.showLegend(true);
-                d3.select('#multiBarChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('width', 500)
-                    .attr('height', 400)
-                    .call(chart);
-            });
-
-
-        </script>
-
-    """
-
-    CHART_FILENAME = "./multibarchart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-
-        if kwargs.get('x_is_date', False):
-            self.set_date_flag(True)
-            self.create_x_axis('xAxis',
-                               format=kwargs.get('x_axis_format', '%d %b %Y'),
-                               date=True)
-            self.set_custom_tooltip_flag(True)
-        else:
-            self.create_x_axis('xAxis', format=kwargs.get('x_axis_format', '.2f'))
-        self.create_y_axis('yAxis', format=kwargs.get('y_axis_format', '.2f'))
-
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/multiBarHorizontalChart.py b/airflow/_vendor/nvd3/multiBarHorizontalChart.py
deleted file mode 100644
index 7e2d5a1..0000000
--- a/airflow/_vendor/nvd3/multiBarHorizontalChart.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class multiBarHorizontalChart(TemplateMixin, NVD3Chart):
-    """
-    A multiple horizontal bar graph contains comparisons of two or more categories or bars.
-
-    Python example::
-
-        from nvd3 import multiBarHorizontalChart
-        chart = multiBarHorizontalChart(name='multiBarHorizontalChart', height=400, width=400)
-        xdata = [-14, -7, 7, 14]
-        ydata = [-6, 5, -1, 9]
-        y2data = [-23, -6, -32, 9]
-
-        extra_serie = {"tooltip": {"y_start": "", "y_end": " balls"}}
-        chart.add_serie(name="Serie 1", y=ydata, x=xdata, extra=extra_serie)
-
-        extra_serie = {"tooltip": {"y_start": "", "y_end": " calls"}}
-        chart.add_serie(name="Serie 2", y=y2data, x=xdata, extra=extra_serie)
-        chart.buildcontent()
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="multiBarHorizontalChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-
-            data_multiBarHorizontalChart=[{"values":
-                [{"y": -6, "x": -14}, {"y": 5, "x": -7}, {"y": -1, "x": 7}, {"y": 9, "x": 14}],
-                "key": "Serie 1", "yAxis": "1"},
-                {"values":
-                    [{"y": -23, "x": -14}, {"y": -6, "x": -7}, {"y": -32, "x": 7}, {"y": 9, "x": 14}],
-                "key": "Serie 2", "yAxis": "1"}];
-
-            nv.addGraph(function() {
-                var chart = nv.models.multiBarHorizontalChart();
-
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-
-                var datum = data_multiBarHorizontalChart;
-
-                        chart.xAxis
-                            .tickFormat(d3.format(',.2f'));
-                        chart.yAxis
-                            .tickFormat(d3.format(',.2f'));
-
-                        chart.tooltipContent(function(key, y, e, graph) {
-                            var x = String(graph.point.x);
-                            var y = String(graph.point.y);
-                                                if(key == 'Serie 1'){
-                                var y =  String(graph.point.y)  + ' balls';
-                            }
-                            if(key == 'Serie 2'){
-                                var y =  String(graph.point.y)  + ' calls';
-                            }
-
-                            tooltip_str = '<center><b>'+key+'</b></center>' + y + ' at ' + x;
-                            return tooltip_str;
-                        });
-
-                    chart.showLegend(true);
-
-                d3.select('#multiBarHorizontalChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('width', 400)
-                    .attr('height', 400)
-                    .call(chart);
-            });
-        </script>
-
-    """
-
-    CHART_FILENAME = "./multibarcharthorizontal.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-
-        self.create_x_axis('xAxis', format=kwargs.get('x_axis_format', '.2f'))
-        self.create_y_axis('yAxis', format=kwargs.get('y_axis_format', '.2f'))
-
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/pieChart.py b/airflow/_vendor/nvd3/pieChart.py
deleted file mode 100644
index bd8990c..0000000
--- a/airflow/_vendor/nvd3/pieChart.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class pieChart(TemplateMixin, NVD3Chart):
-
-    """
-    A pie chart (or a circle graph) is a circular chart divided into sectors,
-    illustrating numerical proportion. In chart, the arc length of each sector
-    is proportional to the quantity it represents.
-
-    Python example::
-
-        from nvd3 import pieChart
-        chart = pieChart(name='pieChart', color_category='category20c',
-                         height=400, width=400)
-
-        xdata = ["Orange", "Banana", "Pear", "Kiwi", "Apple", "Strawbery",
-                 "Pineapple"]
-        ydata = [3, 4, 0, 1, 5, 7, 3]
-
-        extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}}
-        chart.add_serie(y=ydata, x=xdata, extra=extra_serie)
-        chart.buildhtml()
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="pieChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-
-
-            data_pieChart=[{"values": [{"value": 3, "label": "Orange"},
-                           {"value": 4, "label": "Banana"},
-                           {"value": 0, "label": "Pear"},
-                           {"value": 1, "label": "Kiwi"},
-                           {"value": 5, "label": "Apple"},
-                           {"value": 7, "label": "Strawberry"},
-                           {"value": 3, "label": "Pineapple"}],
-                           "key": "Serie 1"}];
-
-            nv.addGraph(function() {
-                var chart = nv.models.pieChart();
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-                var datum = data_pieChart[0].values;
-                        chart.tooltipContent(function(key, y, e, graph) {
-                            var x = String(key);
-                            var y =  String(y)  + ' cal';
-
-                            tooltip_str = '<center><b>'+x+'</b></center>' + y;
-                            return tooltip_str;
-                        });
-                    chart.showLegend(true);
-                    chart.showLabels(true);
-                    chart.donut(false);
-                chart
-                    .x(function(d) { return d.label })
-                    .y(function(d) { return d.value });
-                chart.width(400);
-                chart.height(400);
-
-                d3.select('#pieChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('width', 400)
-                    .attr('height', 400)
-                    .call(chart);  });
-        </script>
-
-    """
-    CHART_FILENAME = "./piechart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-        self.donut = kwargs.get('donut', False)
-        self.donutRatio = kwargs.get('donutRatio', 0.35)
-        self.color_list = []
-        self.create_x_axis('xAxis', format=None)
-        self.create_y_axis('yAxis', format=None)
-        # must have a specified height, otherwise it superimposes both chars
-        if height:
-            self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
-        self.donut = kwargs.get('donut', False)
-        self.donutRatio = kwargs.get('donutRatio', 0.35)
diff --git a/airflow/_vendor/nvd3/scatterChart.py b/airflow/_vendor/nvd3/scatterChart.py
deleted file mode 100644
index 0c044a3..0000000
--- a/airflow/_vendor/nvd3/scatterChart.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class scatterChart(TemplateMixin, NVD3Chart):
-
-    """
-    A scatter plot or scattergraph is a type of mathematical diagram using Cartesian
-    coordinates to display values for two variables for a set of data.
-    The data is displayed as a collection of points, each having the value of one variable
-    determining the position on the horizontal axis and the value of the other variable
-    determining the position on the vertical axis.
-
-    Python example::
-
-        from nvd3 import scatterChart
-        chart = scatterChart(name='scatterChart', height=400, width=400)
-        xdata = [3, 4, 0, -3, 5, 7]
-        ydata = [-1, 2, 3, 3, 15, 2]
-        ydata2 = [1, -2, 4, 7, -5, 3]
-
-        kwargs1 = {'shape': 'circle', 'size': '1'}
-        kwargs2 = {'shape': 'cross', 'size': '10'}
-
-        extra_serie = {"tooltip": {"y_start": "", "y_end": " call"}}
-        chart.add_serie(name="series 1", y=ydata, x=xdata, extra=extra_serie, **kwargs1)
-
-        extra_serie = {"tooltip": {"y_start": "", "y_end": " min"}}
-        chart.add_serie(name="series 2", y=ydata2, x=xdata, extra=extra_serie, **kwargs2)
-        chart.buildhtml()
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="scatterChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-
-        data_scatterChart=[{"values": [{"y": -1, "x": 3, "shape": "circle",
-            "size": "1"}, {"y": 2, "x": 4, "shape": "circle", "size": "1"},
-            {"y": 3, "x": 0, "shape": "circle", "size": "1"},
-            {"y": 3, "x": -3, "shape": "circle", "size": "1"},
-            {"y": 15, "x": 5, "shape": "circle", "size": "1"},
-            {"y": 2, "x": 7, "shape": "circle", "size": "1"}],
-            "key": "series 1", "yAxis": "1"},
-            {"values": [{"y": 1, "x": 3, "shape": "cross", "size": "10"},
-            {"y": -2, "x": 4, "shape": "cross", "size": "10"},
-            {"y": 4, "x": 0, "shape": "cross", "size": "10"},
-            {"y": 7, "x": -3, "shape": "cross", "size": "10"},
-            {"y": -5, "x": 5, "shape": "cross", "size": "10"},
-            {"y": 3, "x": 7, "shape": "cross", "size": "10"}],
-            "key": "series 2", "yAxis": "1"}];
-        nv.addGraph(function() {
-        var chart = nv.models.scatterChart();
-
-        chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-
-        var datum = data_scatterChart;
-
-                chart.xAxis
-                    .tickFormat(d3.format(',.02f'));
-                chart.yAxis
-                    .tickFormat(d3.format(',.02f'));
-
-                chart.tooltipContent(function(key, y, e, graph) {
-                    var x = String(graph.point.x);
-                    var y = String(graph.point.y);
-                                        if(key == 'series 1'){
-                        var y =  String(graph.point.y)  + ' call';
-                    }
-                    if(key == 'series 2'){
-                        var y =  String(graph.point.y)  + ' min';
-                    }
-
-                    tooltip_str = '<center><b>'+key+'</b></center>' + y + ' at ' + x;
-                    return tooltip_str;
-                });
-
-        chart.showLegend(true);
-
-        chart
-        .showDistX(true)
-        .showDistY(true)
-        .color(d3.scale.category10().range());
-
-            d3.select('#scatterChart svg')
-                .datum(datum)
-                .transition().duration(500)
-                .attr('width', 400)
-                .attr('height', 400)
-                .call(chart);
-        });
-        </script>
-
-    """
-
-    CHART_FILENAME = "./scatterchart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-        self.model = 'scatterChart'
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-        self.create_x_axis('xAxis', format=kwargs.get('x_axis_format', '.02f'),
-                           label=kwargs.get('x_axis_label', None))
-        self.create_y_axis('yAxis', format=kwargs.get('y_axis_format', '.02f'),
-                           label=kwargs.get('y_axis_label', None))
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/stackedAreaChart.py b/airflow/_vendor/nvd3/stackedAreaChart.py
deleted file mode 100644
index cfbca4f..0000000
--- a/airflow/_vendor/nvd3/stackedAreaChart.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-"""
-Python-nvd3 is a Python wrapper for NVD3 graph library.
-NVD3 is an attempt to build re-usable charts and chart components
-for d3.js without taking away the power that d3.js gives you.
-
-Project location : https://github.com/areski/python-nvd3
-"""
-
-from .NVD3Chart import NVD3Chart, TemplateMixin
-
-
-class stackedAreaChart(TemplateMixin, NVD3Chart):
-    """
-    The stacked area chart is identical to the area chart, except the areas are stacked
-    on top of each other, rather than overlapping. This can make the chart much easier to read.
-
-    Python example::
-
-        from nvd3 import stackedAreaChart
-        chart = stackedAreaChart(name='stackedAreaChart', height=400, width=400)
-
-        xdata = [100, 101, 102, 103, 104, 105, 106,]
-        ydata = [6, 11, 12, 7, 11, 10, 11]
-        ydata2 = [8, 20, 16, 12, 20, 28, 28]
-
-        extra_serie = {"tooltip": {"y_start": "There is ", "y_end": " min"}}
-        chart.add_serie(name="Serie 1", y=ydata, x=xdata, extra=extra_serie)
-        chart.add_serie(name="Serie 2", y=ydata2, x=xdata, extra=extra_serie)
-        chart.buildhtml()
-
-    Javascript generated:
-
-    .. raw:: html
-
-        <div id="stackedAreaChart"><svg style="height:450px; width:100%"></svg></div>
-        <script>
-
-
-            data_stackedAreaChart=[{"values": [{"y": 6, "x": 100}, {"y": 11, "x": 101}, {"y": 12, "x": 102}, {"y": 7, "x": 103}, {"y": 11, "x": 104}, {"y": 10, "x": 105}, {"y": 11, "x": 106}], "key": "Serie 1", "yAxis": "1"}, {"values": [{"y": 8, "x": 100}, {"y": 20, "x": 101}, {"y": 16, "x": 102}, {"y": 12, "x": 103}, {"y": 20, "x": 104}, {"y": 28, "x": 105}, {"y": 28, "x": 106}], "key": "Serie 2", "yAxis": "1"}];
-            nv.addGraph(function() {
-                var chart = nv.models.stackedAreaChart();
-                chart.margin({top: 30, right: 60, bottom: 20, left: 60});
-                var datum = data_stackedAreaChart;
-                        chart.xAxis
-                            .tickFormat(d3.format(',.2f'));
-                        chart.yAxis
-                            .tickFormat(d3.format(',.2f'));
-
-                        chart.tooltipContent(function(key, y, e, graph) {
-                            var x = String(graph.point.x);
-                            var y = String(graph.point.y);
-                                                if(key == 'Serie 1'){
-                                var y = 'There is ' +  String(graph.point.y)  + ' min';
-                            }
-                            if(key == 'Serie 2'){
-                                var y = 'There is ' +  String(graph.point.y)  + ' min';
-                            }
-
-                            tooltip_str = '<center><b>'+key+'</b></center>' + y + ' at ' + x;
-                            return tooltip_str;
-                        });
-                    chart.showLegend(true);
-                d3.select('#stackedAreaChart svg')
-                    .datum(datum)
-                    .transition().duration(500)
-                    .attr('width', 400)
-                    .attr('height', 400)
-                    .call(chart);
-            });
-        </script>
-
-    """
-
-    CHART_FILENAME = "./stackedareachart.html"
-    template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
-
-    def __init__(self, **kwargs):
-        super().__init__(**kwargs)
-        height = kwargs.get('height', 450)
-        width = kwargs.get('width', None)
-        self.model = 'stackedAreaChart'
-
-        if kwargs.get('x_is_date', False):
-            self.set_date_flag(True)
-            self.create_x_axis('xAxis',
-                               format=kwargs.get('x_axis_format', '%d %b %Y'),
-                               date=True)
-            self.set_custom_tooltip_flag(True)
-        else:
-            self.create_x_axis('xAxis', format=kwargs.get('x_axis_format',
-                                                          '.2f'))
-        self.create_y_axis('yAxis', format=kwargs.get('y_axis_format', '.2f'))
-
-        self.set_graph_height(height)
-        if width:
-            self.set_graph_width(width)
diff --git a/airflow/_vendor/nvd3/templates/base.html b/airflow/_vendor/nvd3/templates/base.html
deleted file mode 100644
index 997e633..0000000
--- a/airflow/_vendor/nvd3/templates/base.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{% block container %}
-{% endblock %}
-
-{% block start_script %}
-    {% if chart.tag_script_js %}
-    <script>
-    {% endif %}
-
-    {% if chart.jquery_on_ready %}
-    $(function(){
-    {% endif %}
-{% endblock start_script %}
-
-{% block body %}
-
-    {% block data %}
-    {% endblock data %}
-
-    {% block inject %}
-    {% endblock inject %}
-
-    {% block foot %}
-    {% endblock foot %}
-     <!-- end of body from base-->
-
-     {% endblock body%}
-
-{% block endscript %}
-    {% if chart.jquery_on_ready %}
-        });
-    {% endif %}
-    {% if chart.tag_script_js %}
-    </script>
-    {% endif %}
-{% endblock endscript %}
diff --git a/airflow/_vendor/nvd3/templates/content.html b/airflow/_vendor/nvd3/templates/content.html
deleted file mode 100644
index 787f39b..0000000
--- a/airflow/_vendor/nvd3/templates/content.html
+++ /dev/null
@@ -1,123 +0,0 @@
-{% extends "base.html" %}
-{% block container %}
-{% if chart.display_container %}
-    {{ chart.container }}
-{% endif %}
-{%  endblock  container %}
-
-{% block body %}
-    {% block data %}
-        data_{{ chart.name }}={{ chart.series_js }};
-    {% endblock data %}
-
-    {% block init %}
-    nv.addGraph(function() {
-        var chart = nv.models.{{ chart.model }}(){% if chart.use_interactive_guideline %}.useInteractiveGuideline(true){% endif %};
-
-        chart.margin({top: {{ chart.margin_top }}, right: {{ chart.margin_right }}, bottom: {{ chart.margin_bottom }}, left: {{ chart.margin_left }}});
-
-        var datum = data_{{ chart.name }};
-
-    {% if not chart.color_list and chart.color_category %}
-        chart.color(d3.scale.{{ chart.color_category }}().range());
-    {% endif %}
-    {% endblock init %}
-
-    {% if chart.stacked %}
-        chart.stacked(true);
-    {% endif %}
-
-    {% block focus %}
-    {% endblock focus %}
-
-
-    {% block axes %}
-        {% for axis, a in chart.axislist.items() %}
-            {% if a.items() %}
-            chart.{{ axis }}
-            {% for attr, value in a.items() %}
-                .{{ attr}}({{ value}}){% if loop.last %};
-                {% endif %}
-            {% endfor %}
-            {% endif %}
-        {% endfor %}
-    {% endblock axes %}
-
-    {# generate custom tooltip for the chart #}
-    {% block tooltip %}
-        {% if chart.custom_tooltip_flag %}
-            {% if not chart.date_flag %}
-                {% if chart.model == 'pieChart' %}
-                    {% block pietooltip %}
-                    {% endblock pietooltip %}
-                {% else %}
-                    chart.tooltipContent(function(key, y, e, graph) {
-                        var x = String(graph.point.x);
-                        var y = String(graph.point.y);
-                        {{ chart.tooltip_condition_string }}
-                        tooltip_str = '<center><b>'+key+'</b></center>' + y + ' at ' + x;
-                        return tooltip_str;
-                    });
-                {% endif %}
-            {% else %}
-                chart.tooltipContent(function(key, y, e, graph) {
-                    var x = d3.time.format("{{ chart.charttooltip_dateformat }}")(new Date(parseInt(graph.point.x)));
-                    var y = String(graph.point.y);
-                    {{ chart.tooltip_condition_string }}
-                    tooltip_str = '<center><b>'+key+'</b></center>' + y + ' on ' + x;
-                    return tooltip_str;
-                });
-            {% endif %}
-        {% endif %}
-    {% endblock tooltip %}
-
-    {# the shape attribute in kwargs is not applied when #}
-    {# not allowing other shapes to be rendered #}
-    {% block legend %}
-      chart.showLegend({{chart.show_legend|lower}});
-    {% endblock legend %}
-
-    {% block custoattr %}
-        {# add custom chart attributes #}
-        {% for attr, value in chart.chart_attr.items() %}
-            {% if value is string and value.startswith(".") %}:
-                chart.{{ attr }}{{ value }};
-            {% else %}
-                chart.{{ attr }}({{ value }});
-            {% endif %}
-        {% endfor %}
-
-        {% if chart.resize %}
-            nv.utils.windowResize(chart.update);
-        {% endif %}
-
-        {# include specific subchart #}
-        {{ chart.jschart }}
-
-    {% endblock custoattr %}
-
-    {% block inject %}
-        {# Inject data to D3 #}
-        d3.select('#{{ chart.name }} svg')
-            .datum(datum)
-            .transition().duration(500)
-            {% if chart.width %}
-            .attr('width', {{ chart.width}})
-            {% endif %}
-            {% if chart.height %}
-            .attr('height', {{ chart.height}})
-            {% endif %}
-            .call(chart);
-    {% endblock inject %}
-
-    {# extra chart attributes #}
-    {% if chart.extras %}
-        {{ chart.extras }}
-    {% endif %}
-
-    {# closing nv.addGraph #}
-    {% block close %}
-    });
-    {% endblock close %}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/cumulativelinechart.html b/airflow/_vendor/nvd3/templates/cumulativelinechart.html
deleted file mode 100644
index 66b6c74..0000000
--- a/airflow/_vendor/nvd3/templates/cumulativelinechart.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{# This template adds attributes unique
-   to cumulativeLineChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-{# calling super guarantees everying in content is also found here ...#}
-{{super()}}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/discretebarchart.html b/airflow/_vendor/nvd3/templates/discretebarchart.html
deleted file mode 100644
index 3a52b3a..0000000
--- a/airflow/_vendor/nvd3/templates/discretebarchart.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{# This is a dummy template, we can use that template to add attributes unique
-   to discreteBarChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-    {% block data %}
-        {{super()}}
-    {% endblock data %}
-
-    {% block init %}
-        {{super()}}
-    {% endblock init %}
-
-    {% block axes %}
-        {{super()}}
-    {% endblock axes %}
-
-    {% block custoattr %}
-    {{super()}}
-    {% endblock custoattr %}
-
-    {% block inject %}
-    {{ super() }}
-    {% endblock inject %}
-
-    {% block close %}
-    {{ super() }}
-    {% endblock close %}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/linebarwfocuschart.html b/airflow/_vendor/nvd3/templates/linebarwfocuschart.html
deleted file mode 100644
index ad4866c..0000000
--- a/airflow/_vendor/nvd3/templates/linebarwfocuschart.html
+++ /dev/null
@@ -1,60 +0,0 @@
-{# This template adds attributes unique
-   to lineChart #}
-
-{% extends "content.html" %}
-{% block body %}
-    {% block data %}
-        data_{{ chart.name }}={{ chart.series_js }};
-    {% endblock data %}
-
-
-    {% block init %}
-        {{super()}}
-    {% endblock init %}
-    {% block axes %}
-        {{super()}}
-    {% endblock axes %}
-    {% block tooltip %}
-        {{super()}}
-    {% endblock tooltip %}
-
-    chart.showLegend({{chart.show_legend|lower}});
-
-    {# add custom chart attributes #}
-    {% for attr, value in chart.chart_attr.items() %}
-        {% if value is string and value.startswith(".") %}:
-            chart.{{ attr }}{{ value }};
-        {% else %}
-            chart.{{ attr }}({{ value }});
-        {% endif %}
-    {% endfor %}
-
-    {% if chart.x_axis_format == 'AM_PM' %}
-        function get_am_pm(d){
-            if (d > 12) {
-                d = d - 12; return (String(d) + 'PM');
-            }
-            else {
-                return (String(d) + 'AM');
-            }
-        };
-    {% else %}
-        chart.x(function(d,i) { return i });
-    {% endif %}
-
-    {% if chart.resize %}
-        nv.utils.windowResize(chart.update);
-    {% endif %}
-    {% block inject %}
-    {{super()}}
-    {% endblock inject %}
-
-		{% if chart.extras %}
-			{{ chart.extras }}
-		{% endif %}
-
-    {% block close %}
-    });
-    {% endblock close %}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/linechart.html b/airflow/_vendor/nvd3/templates/linechart.html
deleted file mode 100644
index edd9633..0000000
--- a/airflow/_vendor/nvd3/templates/linechart.html
+++ /dev/null
@@ -1,46 +0,0 @@
-{# This template adds attributes unique
-   to lineChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-    {% block data %}
-    {{super()}}
-    {% endblock data %}
-
-    {% block init %}
-    {{super()}}
-    {% endblock init %}
-
-    {% block axes %}
-    {{super()}}
-    {% endblock axes %}
-
-    {% if chart.x_axis_format == 'AM_PM' %}
-        function get_am_pm(d){
-            if (d > 12) {
-                d = d - 12; return (String(d) + 'PM');
-            }
-            else {
-                return (String(d) + 'AM');
-            }
-        };
-    {% endif %}
-
-    {% block legend %}
-    {{super()}}
-    {% endblock legend %}
-
-    {% block custoattr %}
-    {{super()}}
-    {% endblock custoattr %}
-
-    {% block inject %}
-    {{ super() }}
-    {% endblock inject %}
-
-    {% block close %}
-    {{ super() }}
-    {% endblock close %}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/lineplusbarchart.html b/airflow/_vendor/nvd3/templates/lineplusbarchart.html
deleted file mode 100644
index 830a192..0000000
--- a/airflow/_vendor/nvd3/templates/lineplusbarchart.html
+++ /dev/null
@@ -1,43 +0,0 @@
-{# This template adds attributes unique
-   to linePlusBarChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-    {% block data %}
-    {{super()}}
-    {% endblock data %}
-
-    {% block init %}
-    {{super()}}
-    {% endblock init %}
-
-    {% block focus %}
-    {% if chart.focus_enable %}
-        chart.focusEnable(true);
-    {% else %}
-        chart.focusEnable(false);
-    {% endif %}
-    {% endblock focus %}
-
-    {% block axes %}
-    {{super()}}
-    {% endblock axes %}
-
-    {% block legend %}
-    {{super()}}
-    {% endblock legend %}
-
-    {% block custoattr %}
-    {{super()}}
-    {% endblock custoattr %}
-
-    {% block inject %}
-    {{ super() }}
-    {% endblock inject %}
-
-    {% block close %}
-    {{ super() }}
-    {% endblock close %}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/linewfocuschart.html b/airflow/_vendor/nvd3/templates/linewfocuschart.html
deleted file mode 100644
index ef02867..0000000
--- a/airflow/_vendor/nvd3/templates/linewfocuschart.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{# This template adds attributes unique
-   to lineWithFocusChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-{# calling super guarantees everying in content is also found here ...#}
-{{super()}}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/multibarchart.html b/airflow/_vendor/nvd3/templates/multibarchart.html
deleted file mode 100644
index 17eae7a..0000000
--- a/airflow/_vendor/nvd3/templates/multibarchart.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{# This template adds attributes unique
-   to multiBarChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-{# calling super guarantees everying in content is also found here ...#}
-{{super()}}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/multibarcharthorizontal.html b/airflow/_vendor/nvd3/templates/multibarcharthorizontal.html
deleted file mode 100644
index 17eae7a..0000000
--- a/airflow/_vendor/nvd3/templates/multibarcharthorizontal.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{# This template adds attributes unique
-   to multiBarChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-{# calling super guarantees everying in content is also found here ...#}
-{{super()}}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/page.html b/airflow/_vendor/nvd3/templates/page.html
deleted file mode 100644
index 2dd0f5d..0000000
--- a/airflow/_vendor/nvd3/templates/page.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-    <head>
-        <meta charset="utf-8" />
-        {% for header_element in chart.header_css+chart.header_js %}
-        {{ header_element }}
-        {% endfor %}
-    </head>
-    <body>
-        {{ chart.content }}
-    </body>
-</html>
diff --git a/airflow/_vendor/nvd3/templates/piechart.html b/airflow/_vendor/nvd3/templates/piechart.html
deleted file mode 100644
index a200e6d..0000000
--- a/airflow/_vendor/nvd3/templates/piechart.html
+++ /dev/null
@@ -1,80 +0,0 @@
-{# This template adds attributes unique
-   to pieChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-    data_{{ chart.name }}={{ chart.series_js }};
-
-    nv.addGraph(function() {
-        var chart = nv.models.{{ chart.model }}(){% if chart.use_interactive_guideline %}.useInteractiveGuideline(true){% endif %};
-        chart.margin({top: {{ chart.margin_top }}, right: {{ chart.margin_right }}, bottom: {{ chart.margin_bottom }}, left: {{ chart.margin_left }}});
-        var datum = data_{{ chart.name }}[0].values;
-
-    {% if not chart.color_list and chart.color_category %}
-        chart.color(d3.scale.{{ chart.color_category }}().range());
-    {% endif %}
-
-    chart.tooltipContent(function(key, y, e, graph) {
-          var x = String(key);
-              {{ chart.tooltip_condition_string }}
-              tooltip_str = '<center><b>'+x+'</b></center>' + y;
-              return tooltip_str;
-              });
-    {# showLabels only supported in pieChart #}
-        chart.showLabels({{chart.show_labels|lower}});
-
-        {% if chart.donut %}
-            chart.donut(true);
-            chart.donutRatio({{ chart.donutRatio }});
-        {% else %}
-            chart.donut(false);
-        {% endif %}
-
-    chart.showLegend({{chart.show_legend|lower}});
-
-    {# add custom chart attributes #}
-    {% for attr, value in chart.chart_attr.items() %}
-        {% if value is string and value.startswith(".") %}:
-            chart.{{ attr }}{{ value }};
-        {% else %}
-            chart.{{ attr }}({{ value }});
-        {% endif %}
-    {% endfor %}
-
-    {% if chart.resize %}
-        nv.utils.windowResize(chart.update);
-    {% endif %}
-
-    {% if chart.color_list %}
-        var mycolor = new Array();
-        {% for color in chart.color_list %}
-            mycolor[{{ loop.index - 1}}] = "{{ color }}";
-        {% endfor %}
-    {% endif %}
-
-        chart
-            .x(function(d) { return d.label })
-            .y(function(d) { return d.value });
-
-    {% if chart.width %}
-        chart.width({{ chart.width }});
-    {% endif %}
-
-    {% if chart.height %}
-        chart.height({{ chart.height }});
-    {% endif %}
-
-    {% if chart.color_list %}
-        chart.color(mycolor);
-    {% endif %}
-
-    {% block inject %}
-    {{super()}}
-    {% endblock inject %}
-
-    {% block close %}
-    {{ super() }}
-    {% endblock close %}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/scatterchart.html b/airflow/_vendor/nvd3/templates/scatterchart.html
deleted file mode 100644
index 8c2adaa..0000000
--- a/airflow/_vendor/nvd3/templates/scatterchart.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{# This template adds attributes unique
-   to  scatterChart #}
-
-{% extends "content.html" %}
-{% block body %}
-
-    {% block data %}
-    {{super()}}
-    {% endblock data %}
-
-    {% block init %}
-    {{super()}}
-    {% endblock init %}
-
-    {% block axes %}
-    {{super()}}
-    {% endblock axes %}
-
-    {% if chart.x_axis_format == 'AM_PM' %}
-        function get_am_pm(d){
-            if (d > 12) {
-                d = d - 12; return (String(d) + 'PM');
-            }
-            else {
-                return (String(d) + 'AM');
-            }
-        };
-    {% endif %}
-
-    {% block legend %}
-    {{super()}}
-    {% endblock legend %}
-
-    {% block custoattr %}
-    {{super()}}
-    {% endblock custoattr %}
-
-    {% block inject %}
-
-    chart
-        .showDistX(true)
-        .showDistY(true)
-        .color(d3.scale.category10().range());
-
-    {{ super() }}
-    {% endblock inject %}
-
-    {% block close %}
-    {{ super() }}
-    {% endblock close %}
-
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/templates/stackedareachart.html b/airflow/_vendor/nvd3/templates/stackedareachart.html
deleted file mode 100644
index b70833d..0000000
--- a/airflow/_vendor/nvd3/templates/stackedareachart.html
+++ /dev/null
@@ -1,7 +0,0 @@
-{# This is a dummy template, we can use that template to add attributes unique
-   to stackedareachart #}
-
-{% extends "content.html" %}
-{% block body %}
-    {{ super() }}
-{% endblock body %}
diff --git a/airflow/_vendor/nvd3/translator.py b/airflow/_vendor/nvd3/translator.py
deleted file mode 100644
index ffde2c2..0000000
--- a/airflow/_vendor/nvd3/translator.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-
-
-class Tag(object):
-    """Tag class"""
-
-    def __init__(self, content=None):
-        self.content = content
-        self.attrs = ' '.join(['%s="%s"' % (attr, value)
-                               for attr, value in self.attrs])
-
-    def __str__(self):
-        return '<%s%s>\n    %s\n</%s>' % (self.name,
-                                          ' ' + self.attrs if self.attrs else '',
-                                          self.content,
-                                          self.name)
-
-
-class ScriptTag(Tag):
-    name = 'script'
-    attrs = (('type', 'text/javascript'),)
-
-
-class AnonymousFunction(object):
-    def __init__(self, arguments, content):
-        self.arguments = arguments
-        self.content = content
-
-    def __str__(self):
-        return 'function(%s) { %s }' % (self.arguments, self.content)
-
-
-class Function(object):
-
-    def __init__(self, name):
-        self.name = name
-        self._calls = []
-
-    def __str__(self):
-        operations = [self.name]
-        operations.extend(str(call) for call in self._calls)
-        return '%s' % ('.'.join(operations),)
-
-    def __getattr__(self, attr):
-        self._calls.append(attr)
-        return self
-
-    def __call__(self, *args):
-        if not args:
-            self._calls[-1] = self._calls[-1] + '()'
-        else:
-            arguments = ','.join([str(arg) for arg in args])
-            self._calls[-1] = self._calls[-1] + '(%s)' % (arguments,)
-        return self
-
-
-class Assignment(object):
-
-    def __init__(self, key, value, scoped=True):
-        self.key = key
-        self.value = value
-        self.scoped = scoped
-
-    def __str__(self):
-        return '%s%s = %s;' % ('var ' if self.scoped else '', self.key, self.value)
-
-
-def indent(func):
-    # TODO: Add indents to function str
-    return str(func)
diff --git a/airflow/_vendor/slugify/LICENSE b/airflow/_vendor/slugify/LICENSE
deleted file mode 100644
index 82af695..0000000
--- a/airflow/_vendor/slugify/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) Val Neekman @ Neekware Inc. http://neekware.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/airflow/_vendor/slugify/__init__.py b/airflow/_vendor/slugify/__init__.py
deleted file mode 100644
index 7358b99..0000000
--- a/airflow/_vendor/slugify/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from .slugify import *
-
-
-__author__ = 'Val Neekman @ Neekware Inc. [@vneekman]'
-__description__ = 'A Python slugify application that also handles Unicode'
-__version__ = '2.0.1'
diff --git a/airflow/_vendor/slugify/slugify.py b/airflow/_vendor/slugify/slugify.py
deleted file mode 100644
index cd88c65..0000000
--- a/airflow/_vendor/slugify/slugify.py
+++ /dev/null
@@ -1,183 +0,0 @@
-import re
-import unicodedata
-import types
-import sys
-
-try:
-    from htmlentitydefs import name2codepoint
-    _unicode = unicode
-    _unicode_type = types.UnicodeType
-except ImportError:
-    from html.entities import name2codepoint
-    _unicode = str
-    _unicode_type = str
-    unichr = chr
-
-import text_unidecode as unidecode
-
-__all__ = ['slugify', 'smart_truncate']
-
-
-CHAR_ENTITY_PATTERN = re.compile(r'&(%s);' % '|'.join(name2codepoint))
-DECIMAL_PATTERN = re.compile(r'&#(\d+);')
-HEX_PATTERN = re.compile(r'&#x([\da-fA-F]+);')
-QUOTE_PATTERN = re.compile(r'[\']+')
-ALLOWED_CHARS_PATTERN = re.compile(r'[^-a-z0-9]+')
-ALLOWED_CHARS_PATTERN_WITH_UPPERCASE = re.compile(r'[^-a-zA-Z0-9]+')
-DUPLICATE_DASH_PATTERN = re.compile(r'-{2,}')
-NUMBERS_PATTERN = re.compile(r'(?<=\d),(?=\d)')
-DEFAULT_SEPARATOR = '-'
-
-
-def smart_truncate(string, max_length=0, word_boundary=False, separator=' ', save_order=False):
-    """
-    Truncate a string.
-    :param string (str): string for modification
-    :param max_length (int): output string length
-    :param word_boundary (bool):
-    :param save_order (bool): if True then word order of output string is like input string
-    :param separator (str): separator between words
-    :return:
-    """
-
-    string = string.strip(separator)
-
-    if not max_length:
-        return string
-
-    if len(string) < max_length:
-        return string
-
-    if not word_boundary:
-        return string[:max_length].strip(separator)
-
-    if separator not in string:
-        return string[:max_length]
-
-    truncated = ''
-    for word in string.split(separator):
-        if word:
-            next_len = len(truncated) + len(word)
-            if next_len < max_length:
-                truncated += '{0}{1}'.format(word, separator)
-            elif next_len == max_length:
-                truncated += '{0}'.format(word)
-                break
-            else:
-                if save_order:
-                    break
-    if not truncated: # pragma: no cover
-        truncated = string[:max_length]
-    return truncated.strip(separator)
-
-
-def slugify(text, entities=True, decimal=True, hexadecimal=True, max_length=0, word_boundary=False,
-            separator=DEFAULT_SEPARATOR, save_order=False, stopwords=(), regex_pattern=None, lowercase=True,
-            replacements=()):
-    """
-    Make a slug from the given text.
-    :param text (str): initial text
-    :param entities (bool):
-    :param decimal (bool):
-    :param hexadecimal (bool):
-    :param max_length (int): output string length
-    :param word_boundary (bool):
-    :param save_order (bool): if parameter is True and max_length > 0 return whole words in the initial order
-    :param separator (str): separator between words
-    :param stopwords (iterable): words to discount
-    :param regex_pattern (str): regex pattern for allowed characters
-    :param lowercase (bool): activate case sensitivity by setting it to False
-    :param replacements (iterable): list of replacement rules e.g. [['|', 'or'], ['%', 'percent']]
-    :return (str):
-    """
-
-    # user-specific replacements
-    if replacements:
-        for old, new in replacements:
-            text = text.replace(old, new)
-
-    # ensure text is unicode
-    if not isinstance(text, _unicode_type):
-        text = _unicode(text, 'utf-8', 'ignore')
-
-    # replace quotes with dashes - pre-process
-    text = QUOTE_PATTERN.sub(DEFAULT_SEPARATOR, text)
-
-    # decode unicode
-    text = unidecode.unidecode(text)
-
-    # ensure text is still in unicode
-    if not isinstance(text, _unicode_type):
-        text = _unicode(text, 'utf-8', 'ignore')
-
-    # character entity reference
-    if entities:
-        text = CHAR_ENTITY_PATTERN.sub(lambda m: unichr(name2codepoint[m.group(1)]), text)
-
-    # decimal character reference
-    if decimal:
-        try:
-            text = DECIMAL_PATTERN.sub(lambda m: unichr(int(m.group(1))), text)
-        except Exception:
-            pass
-
-    # hexadecimal character reference
-    if hexadecimal:
-        try:
-            text = HEX_PATTERN.sub(lambda m: unichr(int(m.group(1), 16)), text)
-        except Exception:
-            pass
-
-    # translate
-    text = unicodedata.normalize('NFKD', text)
-
-    # make the text lowercase (optional)
-    if lowercase:
-        text = text.lower()
-
-    # remove generated quotes -- post-process
-    text = QUOTE_PATTERN.sub('', text)
-
-    # cleanup numbers
-    text = NUMBERS_PATTERN.sub('', text)
-
-    # replace all other unwanted characters
-    if lowercase:
-        pattern = regex_pattern or ALLOWED_CHARS_PATTERN
-    else:
-        pattern = regex_pattern or ALLOWED_CHARS_PATTERN_WITH_UPPERCASE
-    text = re.sub(pattern, DEFAULT_SEPARATOR, text)
-
-    # remove redundant
-    text = DUPLICATE_DASH_PATTERN.sub(DEFAULT_SEPARATOR, text).strip(DEFAULT_SEPARATOR)
-
-    # remove stopwords
-    if stopwords:
-        if lowercase:
-            stopwords_lower = [s.lower() for s in stopwords]
-            words = [w for w in text.split(DEFAULT_SEPARATOR) if w not in stopwords_lower]
-        else:
-            words = [w for w in text.split(DEFAULT_SEPARATOR) if w not in stopwords]
-        text = DEFAULT_SEPARATOR.join(words)
-
-    # finalize user-specific replacements
-    if replacements:
-        for old, new in replacements:
-            text = text.replace(old, new)
-
-    # smart truncate if requested
-    if max_length > 0:
-        text = smart_truncate(text, max_length, word_boundary, DEFAULT_SEPARATOR, save_order)
-
-    if separator != DEFAULT_SEPARATOR:
-        text = text.replace(DEFAULT_SEPARATOR, separator)
-
-    return text
-
-
-def main(): # pragma: no cover
-    if len(sys.argv) < 2:
-        print("Usage %s TEXT TO SLUGIFY" % sys.argv[0])
-    else:
-        text = ' '.join(sys.argv[1:])
-        print(slugify(text))
diff --git a/airflow/www/views.py b/airflow/www/views.py
index d0358f2..bb0a028 100644
--- a/airflow/www/views.py
+++ b/airflow/www/views.py
@@ -33,6 +33,7 @@ from urllib.parse import quote, unquote
 
 import lazy_object_proxy
 import markdown
+import nvd3
 import sqlalchemy as sqla
 from flask import (
     Markup, Response, current_app, escape, flash, jsonify, make_response, redirect, render_template, request,
@@ -51,7 +52,6 @@ from wtforms import SelectField, validators
 
 import airflow
 from airflow import models, settings
-from airflow._vendor import nvd3
 from airflow.api.common.experimental.mark_tasks import (
     set_dag_run_state_to_failed, set_dag_run_state_to_success,
 )
diff --git a/requirements/requirements-python3.6.txt b/requirements/requirements-python3.6.txt
index 8c8825b..d8339fd 100644
--- a/requirements/requirements-python3.6.txt
+++ b/requirements/requirements-python3.6.txt
@@ -307,6 +307,8 @@ python-editor==1.0.4
 python-http-client==3.2.7
 python-jenkins==1.7.0
 python-jose==3.1.0
+python-nvd3==0.15.0
+python-slugify==4.0.0
 python3-openid==3.1.0
 pytz==2020.1
 pytzdata==2019.3
@@ -363,7 +365,7 @@ tabulate==0.8.7
 tblib==1.6.0
 tenacity==4.12.0
 termcolor==1.1.0
-text-unidecode==1.2
+text-unidecode==1.3
 textwrap3==0.9.2
 thrift-sasl==0.4.2
 thrift==0.13.0
diff --git a/requirements/requirements-python3.7.txt b/requirements/requirements-python3.7.txt
index 97a92f4..e7c8712 100644
--- a/requirements/requirements-python3.7.txt
+++ b/requirements/requirements-python3.7.txt
@@ -45,7 +45,7 @@ apispec==1.3.3
 appdirs==1.4.4
 argcomplete==1.11.1
 asn1crypto==1.3.0
-astroid==2.3.3
+astroid==2.4.1
 async-generator==1.10
 async-timeout==3.0.1
 atlasclient==1.0.0
@@ -301,6 +301,8 @@ python-editor==1.0.4
 python-http-client==3.2.7
 python-jenkins==1.7.0
 python-jose==3.1.0
+python-nvd3==0.15.0
+python-slugify==4.0.0
 python3-openid==3.1.0
 pytz==2020.1
 pytzdata==2019.3
@@ -357,7 +359,7 @@ tabulate==0.8.7
 tblib==1.6.0
 tenacity==4.12.0
 termcolor==1.1.0
-text-unidecode==1.2
+text-unidecode==1.3
 textwrap3==0.9.2
 thrift-sasl==0.4.2
 thrift==0.13.0
@@ -379,7 +381,7 @@ virtualenv==20.0.21
 watchtower==0.7.3
 wcwidth==0.2.3
 websocket-client==0.57.0
-wrapt==1.11.2
+wrapt==1.12.1
 xmltodict==0.12.0
 yamllint==1.23.0
 yandexcloud==0.40.0
diff --git a/requirements/setup-3.6.md5 b/requirements/setup-3.6.md5
index 3543f94..92f77d6 100644
--- a/requirements/setup-3.6.md5
+++ b/requirements/setup-3.6.md5
@@ -1 +1 @@
-8911ebb91102709e9d727bcf9c657b5c  /opt/airflow/setup.py
+32d870dee6d1bb1c67471d6cc84d7be0  /opt/airflow/setup.py
diff --git a/requirements/setup-3.7.md5 b/requirements/setup-3.7.md5
index 3543f94..92f77d6 100644
--- a/requirements/setup-3.7.md5
+++ b/requirements/setup-3.7.md5
@@ -1 +1 @@
-8911ebb91102709e9d727bcf9c657b5c  /opt/airflow/setup.py
+32d870dee6d1bb1c67471d6cc84d7be0  /opt/airflow/setup.py
diff --git a/scripts/ci/in_container/_in_container_utils.sh b/scripts/ci/in_container/_in_container_utils.sh
index 7cb12d6..525d797 100644
--- a/scripts/ci/in_container/_in_container_utils.sh
+++ b/scripts/ci/in_container/_in_container_utils.sh
@@ -126,7 +126,6 @@ function in_container_refresh_pylint_todo() {
     find . \
         -path "./airflow/www/node_modules" -prune -o \
         -path "./airflow/www_rbac/node_modules" -prune -o \
-        -path "./airflow/_vendor" -prune -o \
         -path "./airflow/migrations/versions" -prune -o \
         -path "./.eggs" -prune -o \
         -path "./docs/_build" -prune -o \
diff --git a/scripts/ci/in_container/run_pylint_main.sh b/scripts/ci/in_container/run_pylint_main.sh
index bb3188b..ded109f 100755
--- a/scripts/ci/in_container/run_pylint_main.sh
+++ b/scripts/ci/in_container/run_pylint_main.sh
@@ -34,7 +34,6 @@ if [[ ${#@} == "0" ]]; then
     find . \
     -path "./airflow/www/node_modules" -prune -o \
     -path "./airflow/www_rbac/node_modules" -prune -o \
-    -path "./airflow/_vendor" -prune -o \
     -path "./airflow/migrations/versions" -prune -o \
     -path "./.eggs" -prune -o \
     -path "./docs/_build" -prune -o \
diff --git a/setup.cfg b/setup.cfg
index 9feeac7..c67a442 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -64,9 +64,6 @@ plugins =
 [mypy-airflow.migrations.*]
 ignore_errors = True
 
-[mypy-airflow._vendor.*]
-ignore_errors = True
-
 [isort]
 line_length=110
 combine_as_imports = true
@@ -75,4 +72,4 @@ include_trailing_comma = true
 known_first_party=airflow,tests
 multi_line_output=5
 # Need to be consistent with the exclude config defined in pre-commit-config.yaml
-skip=airflow/_vendor,build,.tox,venv
+skip=build,.tox,venv
diff --git a/setup.py b/setup.py
index 2f4245c..9332262 100644
--- a/setup.py
+++ b/setup.py
@@ -711,6 +711,8 @@ INSTALL_REQUIREMENTS = [
     'pygments>=2.0.1, <3.0',
     'python-daemon>=2.1.1, <2.2',
     'python-dateutil>=2.3, <3',
+    'python-nvd3~=0.15.0',
+    'python-slugify>=3.0.0,<5.0',
     'requests>=2.20.0, <3',
     'setproctitle>=1.1.8, <2',
     'sqlalchemy~=1.3',
@@ -718,7 +720,6 @@ INSTALL_REQUIREMENTS = [
     'tabulate>=0.7.5, <0.9',
     'tenacity==4.12.0',
     'termcolor==1.1.0',
-    'text-unidecode==1.2',
     'thrift>=0.9.2',
     'typing;python_version<"3.6"',
     'typing-extensions>=3.7.4;python_version<"3.8"',