You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by sc...@apache.org on 2018/04/13 19:51:39 UTC

[2/4] nifi-fds git commit: update nifi-fds node_module

http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/8b49e224/node_modules/iltorb/build/gyp-mac-tool
----------------------------------------------------------------------
diff --git a/node_modules/iltorb/build/gyp-mac-tool b/node_modules/iltorb/build/gyp-mac-tool
new file mode 100755
index 0000000..8ef02b0
--- /dev/null
+++ b/node_modules/iltorb/build/gyp-mac-tool
@@ -0,0 +1,611 @@
+#!/usr/bin/env python
+# Generated by gyp. Do not edit.
+# Copyright (c) 2012 Google Inc. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Utility functions to perform Xcode-style build steps.
+
+These functions are executed via gyp-mac-tool when using the Makefile generator.
+"""
+
+import fcntl
+import fnmatch
+import glob
+import json
+import os
+import plistlib
+import re
+import shutil
+import string
+import subprocess
+import sys
+import tempfile
+
+
+def main(args):
+  executor = MacTool()
+  exit_code = executor.Dispatch(args)
+  if exit_code is not None:
+    sys.exit(exit_code)
+
+
+class MacTool(object):
+  """This class performs all the Mac tooling steps. The methods can either be
+  executed directly, or dispatched from an argument list."""
+
+  def Dispatch(self, args):
+    """Dispatches a string command to a method."""
+    if len(args) < 1:
+      raise Exception("Not enough arguments")
+
+    method = "Exec%s" % self._CommandifyName(args[0])
+    return getattr(self, method)(*args[1:])
+
+  def _CommandifyName(self, name_string):
+    """Transforms a tool name like copy-info-plist to CopyInfoPlist"""
+    return name_string.title().replace('-', '')
+
+  def ExecCopyBundleResource(self, source, dest, convert_to_binary):
+    """Copies a resource file to the bundle/Resources directory, performing any
+    necessary compilation on each resource."""
+    extension = os.path.splitext(source)[1].lower()
+    if os.path.isdir(source):
+      # Copy tree.
+      # TODO(thakis): This copies file attributes like mtime, while the
+      # single-file branch below doesn't. This should probably be changed to
+      # be consistent with the single-file branch.
+      if os.path.exists(dest):
+        shutil.rmtree(dest)
+      shutil.copytree(source, dest)
+    elif extension == '.xib':
+      return self._CopyXIBFile(source, dest)
+    elif extension == '.storyboard':
+      return self._CopyXIBFile(source, dest)
+    elif extension == '.strings':
+      self._CopyStringsFile(source, dest, convert_to_binary)
+    else:
+      shutil.copy(source, dest)
+
+  def _CopyXIBFile(self, source, dest):
+    """Compiles a XIB file with ibtool into a binary plist in the bundle."""
+
+    # ibtool sometimes crashes with relative paths. See crbug.com/314728.
+    base = os.path.dirname(os.path.realpath(__file__))
+    if os.path.relpath(source):
+      source = os.path.join(base, source)
+    if os.path.relpath(dest):
+      dest = os.path.join(base, dest)
+
+    args = ['xcrun', 'ibtool', '--errors', '--warnings', '--notices',
+        '--output-format', 'human-readable-text', '--compile', dest, source]
+    ibtool_section_re = re.compile(r'/\*.*\*/')
+    ibtool_re = re.compile(r'.*note:.*is clipping its content')
+    ibtoolout = subprocess.Popen(args, stdout=subprocess.PIPE)
+    current_section_header = None
+    for line in ibtoolout.stdout:
+      if ibtool_section_re.match(line):
+        current_section_header = line
+      elif not ibtool_re.match(line):
+        if current_section_header:
+          sys.stdout.write(current_section_header)
+          current_section_header = None
+        sys.stdout.write(line)
+    return ibtoolout.returncode
+
+  def _ConvertToBinary(self, dest):
+    subprocess.check_call([
+        'xcrun', 'plutil', '-convert', 'binary1', '-o', dest, dest])
+
+  def _CopyStringsFile(self, source, dest, convert_to_binary):
+    """Copies a .strings file using iconv to reconvert the input into UTF-16."""
+    input_code = self._DetectInputEncoding(source) or "UTF-8"
+
+    # Xcode's CpyCopyStringsFile / builtin-copyStrings seems to call
+    # CFPropertyListCreateFromXMLData() behind the scenes; at least it prints
+    #     CFPropertyListCreateFromXMLData(): Old-style plist parser: missing
+    #     semicolon in dictionary.
+    # on invalid files. Do the same kind of validation.
+    import CoreFoundation
+    s = open(source, 'rb').read()
+    d = CoreFoundation.CFDataCreate(None, s, len(s))
+    _, error = CoreFoundation.CFPropertyListCreateFromXMLData(None, d, 0, None)
+    if error:
+      return
+
+    fp = open(dest, 'wb')
+    fp.write(s.decode(input_code).encode('UTF-16'))
+    fp.close()
+
+    if convert_to_binary == 'True':
+      self._ConvertToBinary(dest)
+
+  def _DetectInputEncoding(self, file_name):
+    """Reads the first few bytes from file_name and tries to guess the text
+    encoding. Returns None as a guess if it can't detect it."""
+    fp = open(file_name, 'rb')
+    try:
+      header = fp.read(3)
+    except e:
+      fp.close()
+      return None
+    fp.close()
+    if header.startswith("\xFE\xFF"):
+      return "UTF-16"
+    elif header.startswith("\xFF\xFE"):
+      return "UTF-16"
+    elif header.startswith("\xEF\xBB\xBF"):
+      return "UTF-8"
+    else:
+      return None
+
+  def ExecCopyInfoPlist(self, source, dest, convert_to_binary, *keys):
+    """Copies the |source| Info.plist to the destination directory |dest|."""
+    # Read the source Info.plist into memory.
+    fd = open(source, 'r')
+    lines = fd.read()
+    fd.close()
+
+    # Insert synthesized key/value pairs (e.g. BuildMachineOSBuild).
+    plist = plistlib.readPlistFromString(lines)
+    if keys:
+      plist = dict(plist.items() + json.loads(keys[0]).items())
+    lines = plistlib.writePlistToString(plist)
+
+    # Go through all the environment variables and replace them as variables in
+    # the file.
+    IDENT_RE = re.compile(r'[/\s]')
+    for key in os.environ:
+      if key.startswith('_'):
+        continue
+      evar = '${%s}' % key
+      evalue = os.environ[key]
+      lines = string.replace(lines, evar, evalue)
+
+      # Xcode supports various suffices on environment variables, which are
+      # all undocumented. :rfc1034identifier is used in the standard project
+      # template these days, and :identifier was used earlier. They are used to
+      # convert non-url characters into things that look like valid urls --
+      # except that the replacement character for :identifier, '_' isn't valid
+      # in a URL either -- oops, hence :rfc1034identifier was born.
+      evar = '${%s:identifier}' % key
+      evalue = IDENT_RE.sub('_', os.environ[key])
+      lines = string.replace(lines, evar, evalue)
+
+      evar = '${%s:rfc1034identifier}' % key
+      evalue = IDENT_RE.sub('-', os.environ[key])
+      lines = string.replace(lines, evar, evalue)
+
+    # Remove any keys with values that haven't been replaced.
+    lines = lines.split('\n')
+    for i in range(len(lines)):
+      if lines[i].strip().startswith("<string>${"):
+        lines[i] = None
+        lines[i - 1] = None
+    lines = '\n'.join(filter(lambda x: x is not None, lines))
+
+    # Write out the file with variables replaced.
+    fd = open(dest, 'w')
+    fd.write(lines)
+    fd.close()
+
+    # Now write out PkgInfo file now that the Info.plist file has been
+    # "compiled".
+    self._WritePkgInfo(dest)
+
+    if convert_to_binary == 'True':
+      self._ConvertToBinary(dest)
+
+  def _WritePkgInfo(self, info_plist):
+    """This writes the PkgInfo file from the data stored in Info.plist."""
+    plist = plistlib.readPlist(info_plist)
+    if not plist:
+      return
+
+    # Only create PkgInfo for executable types.
+    package_type = plist['CFBundlePackageType']
+    if package_type != 'APPL':
+      return
+
+    # The format of PkgInfo is eight characters, representing the bundle type
+    # and bundle signature, each four characters. If that is missing, four
+    # '?' characters are used instead.
+    signature_code = plist.get('CFBundleSignature', '????')
+    if len(signature_code) != 4:  # Wrong length resets everything, too.
+      signature_code = '?' * 4
+
+    dest = os.path.join(os.path.dirname(info_plist), 'PkgInfo')
+    fp = open(dest, 'w')
+    fp.write('%s%s' % (package_type, signature_code))
+    fp.close()
+
+  def ExecFlock(self, lockfile, *cmd_list):
+    """Emulates the most basic behavior of Linux's flock(1)."""
+    # Rely on exception handling to report errors.
+    fd = os.open(lockfile, os.O_RDONLY|os.O_NOCTTY|os.O_CREAT, 0o666)
+    fcntl.flock(fd, fcntl.LOCK_EX)
+    return subprocess.call(cmd_list)
+
+  def ExecFilterLibtool(self, *cmd_list):
+    """Calls libtool and filters out '/path/to/libtool: file: foo.o has no
+    symbols'."""
+    libtool_re = re.compile(r'^.*libtool: file: .* has no symbols$')
+    libtool_re5 = re.compile(
+        r'^.*libtool: warning for library: ' +
+        r'.* the table of contents is empty ' +
+        r'\(no object file members in the library define global symbols\)$')
+    env = os.environ.copy()
+    # Ref:
+    # http://www.opensource.apple.com/source/cctools/cctools-809/misc/libtool.c
+    # The problem with this flag is that it resets the file mtime on the file to
+    # epoch=0, e.g. 1970-1-1 or 1969-12-31 depending on timezone.
+    env['ZERO_AR_DATE'] = '1'
+    libtoolout = subprocess.Popen(cmd_list, stderr=subprocess.PIPE, env=env)
+    _, err = libtoolout.communicate()
+    for line in err.splitlines():
+      if not libtool_re.match(line) and not libtool_re5.match(line):
+        print >>sys.stderr, line
+    # Unconditionally touch the output .a file on the command line if present
+    # and the command succeeded. A bit hacky.
+    if not libtoolout.returncode:
+      for i in range(len(cmd_list) - 1):
+        if cmd_list[i] == "-o" and cmd_list[i+1].endswith('.a'):
+          os.utime(cmd_list[i+1], None)
+          break
+    return libtoolout.returncode
+
+  def ExecPackageFramework(self, framework, version):
+    """Takes a path to Something.framework and the Current version of that and
+    sets up all the symlinks."""
+    # Find the name of the binary based on the part before the ".framework".
+    binary = os.path.basename(framework).split('.')[0]
+
+    CURRENT = 'Current'
+    RESOURCES = 'Resources'
+    VERSIONS = 'Versions'
+
+    if not os.path.exists(os.path.join(framework, VERSIONS, version, binary)):
+      # Binary-less frameworks don't seem to contain symlinks (see e.g.
+      # chromium's out/Debug/org.chromium.Chromium.manifest/ bundle).
+      return
+
+    # Move into the framework directory to set the symlinks correctly.
+    pwd = os.getcwd()
+    os.chdir(framework)
+
+    # Set up the Current version.
+    self._Relink(version, os.path.join(VERSIONS, CURRENT))
+
+    # Set up the root symlinks.
+    self._Relink(os.path.join(VERSIONS, CURRENT, binary), binary)
+    self._Relink(os.path.join(VERSIONS, CURRENT, RESOURCES), RESOURCES)
+
+    # Back to where we were before!
+    os.chdir(pwd)
+
+  def _Relink(self, dest, link):
+    """Creates a symlink to |dest| named |link|. If |link| already exists,
+    it is overwritten."""
+    if os.path.lexists(link):
+      os.remove(link)
+    os.symlink(dest, link)
+
+  def ExecCompileXcassets(self, keys, *inputs):
+    """Compiles multiple .xcassets files into a single .car file.
+
+    This invokes 'actool' to compile all the inputs .xcassets files. The
+    |keys| arguments is a json-encoded dictionary of extra arguments to
+    pass to 'actool' when the asset catalogs contains an application icon
+    or a launch image.
+
+    Note that 'actool' does not create the Assets.car file if the asset
+    catalogs does not contains imageset.
+    """
+    command_line = [
+      'xcrun', 'actool', '--output-format', 'human-readable-text',
+      '--compress-pngs', '--notices', '--warnings', '--errors',
+    ]
+    is_iphone_target = 'IPHONEOS_DEPLOYMENT_TARGET' in os.environ
+    if is_iphone_target:
+      platform = os.environ['CONFIGURATION'].split('-')[-1]
+      if platform not in ('iphoneos', 'iphonesimulator'):
+        platform = 'iphonesimulator'
+      command_line.extend([
+          '--platform', platform, '--target-device', 'iphone',
+          '--target-device', 'ipad', '--minimum-deployment-target',
+          os.environ['IPHONEOS_DEPLOYMENT_TARGET'], '--compile',
+          os.path.abspath(os.environ['CONTENTS_FOLDER_PATH']),
+      ])
+    else:
+      command_line.extend([
+          '--platform', 'macosx', '--target-device', 'mac',
+          '--minimum-deployment-target', os.environ['MACOSX_DEPLOYMENT_TARGET'],
+          '--compile',
+          os.path.abspath(os.environ['UNLOCALIZED_RESOURCES_FOLDER_PATH']),
+      ])
+    if keys:
+      keys = json.loads(keys)
+      for key, value in keys.iteritems():
+        arg_name = '--' + key
+        if isinstance(value, bool):
+          if value:
+            command_line.append(arg_name)
+        elif isinstance(value, list):
+          for v in value:
+            command_line.append(arg_name)
+            command_line.append(str(v))
+        else:
+          command_line.append(arg_name)
+          command_line.append(str(value))
+    # Note: actool crashes if inputs path are relative, so use os.path.abspath
+    # to get absolute path name for inputs.
+    command_line.extend(map(os.path.abspath, inputs))
+    subprocess.check_call(command_line)
+
+  def ExecMergeInfoPlist(self, output, *inputs):
+    """Merge multiple .plist files into a single .plist file."""
+    merged_plist = {}
+    for path in inputs:
+      plist = self._LoadPlistMaybeBinary(path)
+      self._MergePlist(merged_plist, plist)
+    plistlib.writePlist(merged_plist, output)
+
+  def ExecCodeSignBundle(self, key, resource_rules, entitlements, provisioning):
+    """Code sign a bundle.
+
+    This function tries to code sign an iOS bundle, following the same
+    algorithm as Xcode:
+      1. copy ResourceRules.plist from the user or the SDK into the bundle,
+      2. pick the provisioning profile that best match the bundle identifier,
+         and copy it into the bundle as embedded.mobileprovision,
+      3. copy Entitlements.plist from user or SDK next to the bundle,
+      4. code sign the bundle.
+    """
+    resource_rules_path = self._InstallResourceRules(resource_rules)
+    substitutions, overrides = self._InstallProvisioningProfile(
+        provisioning, self._GetCFBundleIdentifier())
+    entitlements_path = self._InstallEntitlements(
+        entitlements, substitutions, overrides)
+    subprocess.check_call([
+        'codesign', '--force', '--sign', key, '--resource-rules',
+        resource_rules_path, '--entitlements', entitlements_path,
+        os.path.join(
+            os.environ['TARGET_BUILD_DIR'],
+            os.environ['FULL_PRODUCT_NAME'])])
+
+  def _InstallResourceRules(self, resource_rules):
+    """Installs ResourceRules.plist from user or SDK into the bundle.
+
+    Args:
+      resource_rules: string, optional, path to the ResourceRules.plist file
+        to use, default to "${SDKROOT}/ResourceRules.plist"
+
+    Returns:
+      Path to the copy of ResourceRules.plist into the bundle.
+    """
+    source_path = resource_rules
+    target_path = os.path.join(
+        os.environ['BUILT_PRODUCTS_DIR'],
+        os.environ['CONTENTS_FOLDER_PATH'],
+        'ResourceRules.plist')
+    if not source_path:
+      source_path = os.path.join(
+          os.environ['SDKROOT'], 'ResourceRules.plist')
+    shutil.copy2(source_path, target_path)
+    return target_path
+
+  def _InstallProvisioningProfile(self, profile, bundle_identifier):
+    """Installs embedded.mobileprovision into the bundle.
+
+    Args:
+      profile: string, optional, short name of the .mobileprovision file
+        to use, if empty or the file is missing, the best file installed
+        will be used
+      bundle_identifier: string, value of CFBundleIdentifier from Info.plist
+
+    Returns:
+      A tuple containing two dictionary: variables substitutions and values
+      to overrides when generating the entitlements file.
+    """
+    source_path, provisioning_data, team_id = self._FindProvisioningProfile(
+        profile, bundle_identifier)
+    target_path = os.path.join(
+        os.environ['BUILT_PRODUCTS_DIR'],
+        os.environ['CONTENTS_FOLDER_PATH'],
+        'embedded.mobileprovision')
+    shutil.copy2(source_path, target_path)
+    substitutions = self._GetSubstitutions(bundle_identifier, team_id + '.')
+    return substitutions, provisioning_data['Entitlements']
+
+  def _FindProvisioningProfile(self, profile, bundle_identifier):
+    """Finds the .mobileprovision file to use for signing the bundle.
+
+    Checks all the installed provisioning profiles (or if the user specified
+    the PROVISIONING_PROFILE variable, only consult it) and select the most
+    specific that correspond to the bundle identifier.
+
+    Args:
+      profile: string, optional, short name of the .mobileprovision file
+        to use, if empty or the file is missing, the best file installed
+        will be used
+      bundle_identifier: string, value of CFBundleIdentifier from Info.plist
+
+    Returns:
+      A tuple of the path to the selected provisioning profile, the data of
+      the embedded plist in the provisioning profile and the team identifier
+      to use for code signing.
+
+    Raises:
+      SystemExit: if no .mobileprovision can be used to sign the bundle.
+    """
+    profiles_dir = os.path.join(
+        os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles')
+    if not os.path.isdir(profiles_dir):
+      print >>sys.stderr, (
+          'cannot find mobile provisioning for %s' % bundle_identifier)
+      sys.exit(1)
+    provisioning_profiles = None
+    if profile:
+      profile_path = os.path.join(profiles_dir, profile + '.mobileprovision')
+      if os.path.exists(profile_path):
+        provisioning_profiles = [profile_path]
+    if not provisioning_profiles:
+      provisioning_profiles = glob.glob(
+          os.path.join(profiles_dir, '*.mobileprovision'))
+    valid_provisioning_profiles = {}
+    for profile_path in provisioning_profiles:
+      profile_data = self._LoadProvisioningProfile(profile_path)
+      app_id_pattern = profile_data.get(
+          'Entitlements', {}).get('application-identifier', '')
+      for team_identifier in profile_data.get('TeamIdentifier', []):
+        app_id = '%s.%s' % (team_identifier, bundle_identifier)
+        if fnmatch.fnmatch(app_id, app_id_pattern):
+          valid_provisioning_profiles[app_id_pattern] = (
+              profile_path, profile_data, team_identifier)
+    if not valid_provisioning_profiles:
+      print >>sys.stderr, (
+          'cannot find mobile provisioning for %s' % bundle_identifier)
+      sys.exit(1)
+    # If the user has multiple provisioning profiles installed that can be
+    # used for ${bundle_identifier}, pick the most specific one (ie. the
+    # provisioning profile whose pattern is the longest).
+    selected_key = max(valid_provisioning_profiles, key=lambda v: len(v))
+    return valid_provisioning_profiles[selected_key]
+
+  def _LoadProvisioningProfile(self, profile_path):
+    """Extracts the plist embedded in a provisioning profile.
+
+    Args:
+      profile_path: string, path to the .mobileprovision file
+
+    Returns:
+      Content of the plist embedded in the provisioning profile as a dictionary.
+    """
+    with tempfile.NamedTemporaryFile() as temp:
+      subprocess.check_call([
+          'security', 'cms', '-D', '-i', profile_path, '-o', temp.name])
+      return self._LoadPlistMaybeBinary(temp.name)
+
+  def _MergePlist(self, merged_plist, plist):
+    """Merge |plist| into |merged_plist|."""
+    for key, value in plist.iteritems():
+      if isinstance(value, dict):
+        merged_value = merged_plist.get(key, {})
+        if isinstance(merged_value, dict):
+          self._MergePlist(merged_value, value)
+          merged_plist[key] = merged_value
+        else:
+          merged_plist[key] = value
+      else:
+        merged_plist[key] = value
+
+  def _LoadPlistMaybeBinary(self, plist_path):
+    """Loads into a memory a plist possibly encoded in binary format.
+
+    This is a wrapper around plistlib.readPlist that tries to convert the
+    plist to the XML format if it can't be parsed (assuming that it is in
+    the binary format).
+
+    Args:
+      plist_path: string, path to a plist file, in XML or binary format
+
+    Returns:
+      Content of the plist as a dictionary.
+    """
+    try:
+      # First, try to read the file using plistlib that only supports XML,
+      # and if an exception is raised, convert a temporary copy to XML and
+      # load that copy.
+      return plistlib.readPlist(plist_path)
+    except:
+      pass
+    with tempfile.NamedTemporaryFile() as temp:
+      shutil.copy2(plist_path, temp.name)
+      subprocess.check_call(['plutil', '-convert', 'xml1', temp.name])
+      return plistlib.readPlist(temp.name)
+
+  def _GetSubstitutions(self, bundle_identifier, app_identifier_prefix):
+    """Constructs a dictionary of variable substitutions for Entitlements.plist.
+
+    Args:
+      bundle_identifier: string, value of CFBundleIdentifier from Info.plist
+      app_identifier_prefix: string, value for AppIdentifierPrefix
+
+    Returns:
+      Dictionary of substitutions to apply when generating Entitlements.plist.
+    """
+    return {
+      'CFBundleIdentifier': bundle_identifier,
+      'AppIdentifierPrefix': app_identifier_prefix,
+    }
+
+  def _GetCFBundleIdentifier(self):
+    """Extracts CFBundleIdentifier value from Info.plist in the bundle.
+
+    Returns:
+      Value of CFBundleIdentifier in the Info.plist located in the bundle.
+    """
+    info_plist_path = os.path.join(
+        os.environ['TARGET_BUILD_DIR'],
+        os.environ['INFOPLIST_PATH'])
+    info_plist_data = self._LoadPlistMaybeBinary(info_plist_path)
+    return info_plist_data['CFBundleIdentifier']
+
+  def _InstallEntitlements(self, entitlements, substitutions, overrides):
+    """Generates and install the ${BundleName}.xcent entitlements file.
+
+    Expands variables "$(variable)" pattern in the source entitlements file,
+    add extra entitlements defined in the .mobileprovision file and the copy
+    the generated plist to "${BundlePath}.xcent".
+
+    Args:
+      entitlements: string, optional, path to the Entitlements.plist template
+        to use, defaults to "${SDKROOT}/Entitlements.plist"
+      substitutions: dictionary, variable substitutions
+      overrides: dictionary, values to add to the entitlements
+
+    Returns:
+      Path to the generated entitlements file.
+    """
+    source_path = entitlements
+    target_path = os.path.join(
+        os.environ['BUILT_PRODUCTS_DIR'],
+        os.environ['PRODUCT_NAME'] + '.xcent')
+    if not source_path:
+      source_path = os.path.join(
+          os.environ['SDKROOT'],
+          'Entitlements.plist')
+    shutil.copy2(source_path, target_path)
+    data = self._LoadPlistMaybeBinary(target_path)
+    data = self._ExpandVariables(data, substitutions)
+    if overrides:
+      for key in overrides:
+        if key not in data:
+          data[key] = overrides[key]
+    plistlib.writePlist(data, target_path)
+    return target_path
+
+  def _ExpandVariables(self, data, substitutions):
+    """Expands variables "$(variable)" in data.
+
+    Args:
+      data: object, can be either string, list or dictionary
+      substitutions: dictionary, variable substitutions to perform
+
+    Returns:
+      Copy of data where each references to "$(variable)" has been replaced
+      by the corresponding value found in substitutions, or left intact if
+      the key was not found.
+    """
+    if isinstance(data, str):
+      for key, value in substitutions.iteritems():
+        data = data.replace('$(%s)' % key, value)
+      return data
+    if isinstance(data, list):
+      return [self._ExpandVariables(v, substitutions) for v in data]
+    if isinstance(data, dict):
+      return {k: self._ExpandVariables(data[k], substitutions) for k in data}
+    return data
+
+if __name__ == '__main__':
+  sys.exit(main(sys.argv[1:]))

http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/8b49e224/node_modules/iltorb/build/iltorb.target.mk
----------------------------------------------------------------------
diff --git a/node_modules/iltorb/build/iltorb.target.mk b/node_modules/iltorb/build/iltorb.target.mk
new file mode 100644
index 0000000..3019d43
--- /dev/null
+++ b/node_modules/iltorb/build/iltorb.target.mk
@@ -0,0 +1,225 @@
+# This file is generated by gyp; do not edit.
+
+TOOLSET := target
+TARGET := iltorb
+DEFS_Debug := \
+	'-DNODE_GYP_MODULE_NAME=iltorb' \
+	'-DUSING_UV_SHARED=1' \
+	'-DUSING_V8_SHARED=1' \
+	'-DV8_DEPRECATION_WARNINGS=1' \
+	'-D_DARWIN_USE_64_BIT_INODE=1' \
+	'-D_LARGEFILE_SOURCE' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNOMINMAX' \
+	'-DBUILDING_NODE_EXTENSION' \
+	'-DDEBUG' \
+	'-D_DEBUG' \
+	'-DV8_ENABLE_CHECKS'
+
+# Flags passed to all source files.
+CFLAGS_Debug := \
+	-O0 \
+	-gdwarf-2 \
+	-mmacosx-version-min=10.7 \
+	-arch x86_64 \
+	-Wall \
+	-Wendif-labels \
+	-W \
+	-Wno-unused-parameter
+
+# Flags passed to only C files.
+CFLAGS_C_Debug := \
+	-fno-strict-aliasing \
+	-O2
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Debug := \
+	-std=gnu++0x \
+	-stdlib=libc++ \
+	-fno-rtti \
+	-fno-exceptions \
+	-fno-threadsafe-statics \
+	-fno-strict-aliasing \
+	-O2
+
+# Flags passed to only ObjC files.
+CFLAGS_OBJC_Debug :=
+
+# Flags passed to only ObjC++ files.
+CFLAGS_OBJCC_Debug :=
+
+INCS_Debug := \
+	-I/Users/scottyaslan/.node-gyp/9.11.1/include/node \
+	-I/Users/scottyaslan/.node-gyp/9.11.1/src \
+	-I/Users/scottyaslan/.node-gyp/9.11.1/deps/uv/include \
+	-I/Users/scottyaslan/.node-gyp/9.11.1/deps/v8/include \
+	-I$(srcdir)/../nan \
+	-I$(srcdir)/brotli/include
+
+DEFS_Release := \
+	'-DNODE_GYP_MODULE_NAME=iltorb' \
+	'-DUSING_UV_SHARED=1' \
+	'-DUSING_V8_SHARED=1' \
+	'-DV8_DEPRECATION_WARNINGS=1' \
+	'-D_DARWIN_USE_64_BIT_INODE=1' \
+	'-D_LARGEFILE_SOURCE' \
+	'-D_FILE_OFFSET_BITS=64' \
+	'-DNOMINMAX' \
+	'-DBUILDING_NODE_EXTENSION'
+
+# Flags passed to all source files.
+CFLAGS_Release := \
+	-Os \
+	-gdwarf-2 \
+	-mmacosx-version-min=10.7 \
+	-arch x86_64 \
+	-Wall \
+	-Wendif-labels \
+	-W \
+	-Wno-unused-parameter
+
+# Flags passed to only C files.
+CFLAGS_C_Release := \
+	-fno-strict-aliasing \
+	-O2
+
+# Flags passed to only C++ files.
+CFLAGS_CC_Release := \
+	-std=gnu++0x \
+	-stdlib=libc++ \
+	-fno-rtti \
+	-fno-exceptions \
+	-fno-threadsafe-statics \
+	-fno-strict-aliasing \
+	-O2
+
+# Flags passed to only ObjC files.
+CFLAGS_OBJC_Release :=
+
+# Flags passed to only ObjC++ files.
+CFLAGS_OBJCC_Release :=
+
+INCS_Release := \
+	-I/Users/scottyaslan/.node-gyp/9.11.1/include/node \
+	-I/Users/scottyaslan/.node-gyp/9.11.1/src \
+	-I/Users/scottyaslan/.node-gyp/9.11.1/deps/uv/include \
+	-I/Users/scottyaslan/.node-gyp/9.11.1/deps/v8/include \
+	-I$(srcdir)/../nan \
+	-I$(srcdir)/brotli/include
+
+OBJS := \
+	$(obj).target/$(TARGET)/brotli/common/dictionary.o \
+	$(obj).target/$(TARGET)/brotli/dec/bit_reader.o \
+	$(obj).target/$(TARGET)/brotli/dec/decode.o \
+	$(obj).target/$(TARGET)/brotli/dec/huffman.o \
+	$(obj).target/$(TARGET)/brotli/dec/state.o \
+	$(obj).target/$(TARGET)/brotli/enc/backward_references.o \
+	$(obj).target/$(TARGET)/brotli/enc/backward_references_hq.o \
+	$(obj).target/$(TARGET)/brotli/enc/bit_cost.o \
+	$(obj).target/$(TARGET)/brotli/enc/block_splitter.o \
+	$(obj).target/$(TARGET)/brotli/enc/brotli_bit_stream.o \
+	$(obj).target/$(TARGET)/brotli/enc/cluster.o \
+	$(obj).target/$(TARGET)/brotli/enc/compress_fragment.o \
+	$(obj).target/$(TARGET)/brotli/enc/compress_fragment_two_pass.o \
+	$(obj).target/$(TARGET)/brotli/enc/dictionary_hash.o \
+	$(obj).target/$(TARGET)/brotli/enc/encode.o \
+	$(obj).target/$(TARGET)/brotli/enc/entropy_encode.o \
+	$(obj).target/$(TARGET)/brotli/enc/histogram.o \
+	$(obj).target/$(TARGET)/brotli/enc/literal_cost.o \
+	$(obj).target/$(TARGET)/brotli/enc/memory.o \
+	$(obj).target/$(TARGET)/brotli/enc/metablock.o \
+	$(obj).target/$(TARGET)/brotli/enc/static_dict.o \
+	$(obj).target/$(TARGET)/brotli/enc/utf8_util.o \
+	$(obj).target/$(TARGET)/src/common/allocator.o \
+	$(obj).target/$(TARGET)/src/common/stream_coder.o \
+	$(obj).target/$(TARGET)/src/dec/stream_decode.o \
+	$(obj).target/$(TARGET)/src/dec/stream_decode_worker.o \
+	$(obj).target/$(TARGET)/src/enc/stream_encode.o \
+	$(obj).target/$(TARGET)/src/enc/stream_encode_worker.o \
+	$(obj).target/$(TARGET)/src/iltorb.o
+
+# Add to the list of files we specially track dependencies for.
+all_deps += $(OBJS)
+
+# CFLAGS et al overrides must be target-local.
+# See "Target-specific Variable Values" in the GNU Make manual.
+$(OBJS): TOOLSET := $(TOOLSET)
+$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE))
+$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE))
+$(OBJS): GYP_OBJCFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) $(CFLAGS_OBJC_$(BUILDTYPE))
+$(OBJS): GYP_OBJCXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE))  $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) $(CFLAGS_OBJCC_$(BUILDTYPE))
+
+# Suffix rules, putting all outputs into $(obj).
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD
+	@$(call do_cmd,cxx,1)
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.c FORCE_DO_CMD
+	@$(call do_cmd,cc,1)
+
+# Try building from generated source, too.
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD
+	@$(call do_cmd,cxx,1)
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD
+	@$(call do_cmd,cc,1)
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD
+	@$(call do_cmd,cxx,1)
+
+$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
+	@$(call do_cmd,cc,1)
+
+# End of this set of suffix rules
+### Rules for final target.
+LDFLAGS_Debug := \
+	-undefined dynamic_lookup \
+	-Wl,-no_pie \
+	-Wl,-search_paths_first \
+	-mmacosx-version-min=10.7 \
+	-arch x86_64 \
+	-L$(builddir) \
+	-stdlib=libc++
+
+LIBTOOLFLAGS_Debug := \
+	-undefined dynamic_lookup \
+	-Wl,-no_pie \
+	-Wl,-search_paths_first
+
+LDFLAGS_Release := \
+	-undefined dynamic_lookup \
+	-Wl,-no_pie \
+	-Wl,-search_paths_first \
+	-mmacosx-version-min=10.7 \
+	-arch x86_64 \
+	-L$(builddir) \
+	-stdlib=libc++
+
+LIBTOOLFLAGS_Release := \
+	-undefined dynamic_lookup \
+	-Wl,-no_pie \
+	-Wl,-search_paths_first
+
+LIBS :=
+
+$(builddir)/iltorb.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE))
+$(builddir)/iltorb.node: LIBS := $(LIBS)
+$(builddir)/iltorb.node: GYP_LIBTOOLFLAGS := $(LIBTOOLFLAGS_$(BUILDTYPE))
+$(builddir)/iltorb.node: TOOLSET := $(TOOLSET)
+$(builddir)/iltorb.node: $(OBJS) FORCE_DO_CMD
+	$(call do_cmd,solink_module)
+
+all_deps += $(builddir)/iltorb.node
+# Add target alias
+.PHONY: iltorb
+iltorb: $(builddir)/iltorb.node
+
+# Short alias for building this executable.
+.PHONY: iltorb.node
+iltorb.node: $(builddir)/iltorb.node
+
+# Add executable to "all" target.
+.PHONY: all
+all: $(builddir)/iltorb.node
+

http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/8b49e224/node_modules/jquery/package.json
----------------------------------------------------------------------
diff --git a/node_modules/jquery/package.json b/node_modules/jquery/package.json
index 70a6e2f..8b095b1 100644
--- a/node_modules/jquery/package.json
+++ b/node_modules/jquery/package.json
@@ -22,7 +22,8 @@
     "fetchSpec": "3.2.1"
   },
   "_requiredBy": [
-    "/"
+    "/",
+    "/nifi-fds"
   ],
   "_resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz",
   "_spec": "3.2.1",

http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/8b49e224/node_modules/nifi-fds/package.json
----------------------------------------------------------------------
diff --git a/node_modules/nifi-fds/package.json b/node_modules/nifi-fds/package.json
index 3032823..6854d0c 100644
--- a/node_modules/nifi-fds/package.json
+++ b/node_modules/nifi-fds/package.json
@@ -17,7 +17,7 @@
   "_requiredBy": [
     "/"
   ],
-  "_resolved": "git://github.com/apache/nifi-fds.git#afebff3531e8c7f51bf41b215a24601104fa106d",
+  "_resolved": "git://github.com/apache/nifi-fds.git#4eee1d77635dd5cd3fe03eb77efa724935a0cd3d",
   "_spec": "nifi-fds@git://github.com/apache/nifi-fds.git",
   "_where": "/Users/scottyaslan/Development/nifi-fds",
   "author": {

http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/8b49e224/node_modules/nifi-fds/platform/core/common/styles/_progress-bar.scss
----------------------------------------------------------------------
diff --git a/node_modules/nifi-fds/platform/core/common/styles/_progress-bar.scss b/node_modules/nifi-fds/platform/core/common/styles/_progress-bar.scss
new file mode 100644
index 0000000..4ec81d6
--- /dev/null
+++ b/node_modules/nifi-fds/platform/core/common/styles/_progress-bar.scss
@@ -0,0 +1,20 @@
+/*
+* 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.
+*/
+
+body[fds] .mat-progress-bar-buffer {
+    background-color: $grey4;
+}

http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/8b49e224/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css
----------------------------------------------------------------------
diff --git a/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css b/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css
index 4f12b1d..09d81be 100644
--- a/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css
+++ b/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css
@@ -1,3 +1,3 @@
-@font-face{font-family:'Roboto';font-style:normal;font-weight:300;src:local("Roboto Light"),local("Roboto-Light"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-Light.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:italic;font-weight:300;src:local("Roboto LightItalic"),local("Roboto-LightItalic"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-LightItalic.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:normal;font-weight:normal;src:local("Roboto Regular"),local("Roboto-Regular"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-Regular.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:normal;font-weight:500;src:local("Roboto Medium"),local("Roboto-Medium"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-Medium.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:normal;font-weight:bold;src:local("Roboto Bo
 ld"),local("Roboto-Bold"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-Bold.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:italic;font-weight:normal;src:local("Roboto Italic"),local("Roboto-Italic"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-RegularItalic.ttf") format("truetype")}@font-face{font-family:'Roboto Slab';font-style:normal;font-weight:normal;src:local("RobotoSlab Regular"),local("RobotoSlab-Regular"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto-Slab/Roboto-Slab-Regular.ttf") format("truetype")}@font-face{font-family:'Roboto Slab';font-style:normal;font-weight:bold;src:local("RobotoSlab Bold"),local("RobotoSlab-Bold"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto-Slab/Roboto-Slab-Bold.ttf") format("truetype")}body,html{height:100%}body,button,input,label,select,td,textarea{font-family:"Roboto",sans-serif;font-size:14px}body{color:#333}strong{font-
 weight:bold}pre{overflow-x:auto}em{font-style:italic}h1,h2,h3,h4,h5,h6{font-family:"Roboto",sans-serif;font-weight:normal;font-style:normal;background:#FFFFFF}h1{color:#333}h2{color:#666}table{font-family:"Roboto",sans-serif;font-size:13px;color:#666}.camel-case{text-transform:capitalize}.header{font-family:"Roboto Medium",sans-serif;font-size:16px;color:#333;padding-bottom:10px}.help-icon{font-size:12px;color:#1491C1}.details-header{height:92px}.details-header-container{position:relative;top:22px;left:10px}.description{font-family:"Roboto Light",sans-serif;font-size:12px;color:#666}.description i{padding-right:5px}.label{font-family:"Roboto Medium",sans-serif;font-size:14px;color:#333;text-transform:uppercase}.units{font-family:"Roboto Light",sans-serif;font-size:14px;color:#333}.align-vertical{margin-top:auto;margin-bottom:auto}.align-horizontal{margin-left:auto;margin-right:auto}.fill-available-width{width:100%}.pointer{cursor:pointer}body[fds] .expansion-panel-filter-toggle-grou
 p{box-shadow:none !important}body[fds] .expansion-panel-filter-toggle-group .mat-button-toggle{height:75px;width:125px;border:1px solid #ccc}body[fds] .expansion-panel-filter-toggle-group .mat-button-toggle-label-content{height:100%;width:100%;padding:0;line-height:63px;text-align:center}body[fds] .expansion-panel-filter-toggle-group .mat-button-toggle-checked{background-color:#6B8791;color:white}body[fds] .expansion-panel-filter-toggle-group .mat-button-toggle-checked .md-display-1{color:white}body[fds] .expansion-panel-filter-toggle-group .md-display-1{color:#6B8791}body[fds] .expansion-panel-filter-toggle-group div{line-height:normal}body[fds] .tab-toggle-group{box-shadow:none !important}body[fds] .tab-toggle-group .mat-button-toggle-label-content{border-bottom:2px solid #eee}body[fds] .tab-toggle-group .mat-button-toggle-checked{background:transparent}body[fds] .tab-toggle-group .mat-button-toggle-checked .mat-button-toggle-label-content{border-bottom:2px solid #6B8791;backgroun
 d:transparent}body[fds] .on-off-toggle-group{box-shadow:none !important}body[fds] .on-off-toggle-group .mat-button-toggle{height:20px;width:35px;border:1px solid #ccc}body[fds] .on-off-toggle-group .mat-button-toggle-label-content{height:100%;width:100%;padding:0;line-height:20px;text-align:center}body[fds] .on-off-toggle-group .mat-button-toggle-checked{background-color:#6B8791;color:white;border:1px solid #6B8791}body[fds] .off-toggle.mat-button-toggle-checked{background-color:#ccc;color:#333;border:1px solid #ccc}body[fds] .mat-checkbox-inner-container{height:10px !important;width:10px !important}body[fds] .mat-checkbox-frame{height:10px;width:10px;border-color:#ddd}body[fds] .mat-checkbox-ripple{left:-7px;top:-7px;right:-7px;bottom:-7px}body[fds] .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background,body[fds] .mat-checkbox-checked.mat-accent .mat-checkbox-background{background-color:#6B8791}body[fds] .mat-checkbox-inner-container:hover{background-color:#6B8791;border-r
 adius:2px}body[fds] .mat-checkbox-background{height:10px;width:10px}body[fds] .mat-pseudo-checkbox{height:10px !important;width:10px !important;border:1px solid #ddd}body[fds] .mat-pseudo-checkbox:hover{background-color:#6B8791;border:1px solid #6B8791}body[fds] .mat-pseudo-checkbox-checked::after{content:'\f00c';font-size:8px;font-family:fontawesome;margin-top:-9px;margin-left:-1px;border:none;transform:initial}body[fds] .mat-pseudo-checkbox-checked,body[fds] .mat-pseudo-checkbox-indeterminate{background-color:#6B8791;border:1px solid #6B8791;height:10px;width:10px}body[fds] .mat-checkbox-disabled{cursor:not-allowed}body[fds] .mat-radio-container{height:12px;width:12px}body[fds] .mat-radio-outer-circle{height:12px;width:12px;background-color:#FFFFFF;border:1px solid #ddd}body[fds] .mat-radio-outer-circle:hover{background-color:#6B8791;border-color:#6B8791}body[fds] .mat-radio-checked .mat-radio-outer-circle{border:1px solid #6B8791;background-color:#6B8791}body[fds] .mat-radio-butt
 on.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#6B8791}body[fds] .mat-radio-inner-circle{height:10px;width:10px;left:1px;top:1px;background-color:#FFFFFF}body[fds] .mat-radio-checked .mat-radio-inner-circle{background-color:#FFFFFF}body[fds] .mat-chip{border-radius:2px;font-size:10px;font-family:"Roboto",sans-serif;font-style:normal;font-weight:normal;padding:4px 12px 4px 12px}body[fds] .mat-chip i{margin-left:10px;float:right;margin-top:2px}body[fds] .mat-basic-chip{color:#666;height:24px;margin:22px 8px 0 0}body[fds] .mat-basic-chip.td-chip-after-pad{padding:4px 12px 4px 12px}body[fds] .mat-basic-chip i{margin-left:10px;float:right;margin-top:2px}body[fds] .mat-basic-chip .td-chip{font-size:10px;min-height:unset;line-height:20px;position:relative;top:-2px}body[fds] .td-chip span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:65px}body[fds] .td-chip-disabled .td-chip{padding:0px 0px 0px 12px}body[fds] .mat-basic-chip mat-icon.td-chip-removal{f
 ont-size:15px;margin-bottom:7px}body[fds] .mat-dialog-container{padding:20px;width:400px}body[fds] .mat-tab-label{line-height:72px;text-transform:uppercase;color:#666}body[fds] .mat-tab-label:hover:not([disabled]){color:#333}body[fds] .mat-tab-label:focus:not([disabled]){background-color:#FFFFFF}body[fds] .mat-tab-label-active{color:#333}body[fds] .mat-tab-nav-bar,body[fds] .mat-tab-header{border-bottom:0px}body[fds] .mat-input-container{min-width:200px}body[fds] .mat-input-wrapper{margin:0;padding-bottom:0}body[fds] input.mat-input-element,body[fds] textarea.mat-input-element{border-radius:2px;color:#666;border:1px solid #CFD3D7;height:32px;padding:0px 10px;width:calc(100% - 26px)}body[fds] textarea.mat-input-element{padding:10px 10px}body[fds] input.mat-input-element[disabled],body[fds] textarea.mat-input-element[disabled]{background:#b2b8c1;color:#dbdee2;border:1px solid #b2b8c1}body[fds] .mat-input-subscript-wrapper{margin-top:18px;width:calc(100% - 23px)}body[fds] input.mat-inp
 ut-element:focus,body[fds] textarea.mat-input-element:focus{border-color:#6B8791}body[fds] .mat-input-underline{display:none}body[fds] .mat-input-placeholder{font-size:14px;color:#999;font-weight:300}body[fds] .mat-input-placeholder{top:29px;left:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:calc(100% - 44px)}body[fds] mat-input-container.mat-focused .mat-input-placeholder{transform:translateY(-26px) translateX(-10px) scale(0.75)}body[fds] .mat-form-field-can-float.mat-form-field-should-float .mat-form-field-placeholder{transform:translateY(-26px) translateX(-10px) scale(0.75)}body[fds] .mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-placeholder-wrapper .mat-form-field-placeholder{transform:translateY(-26px) translateX(-10px) scale(0.75)}body[fds] .input-button{top:5px;left:-4px;border-left:none !important}body[fds] .input-button.mat-raised-button[disabled]{opacity:1}body[fds] td-chips .mat-input-placeholder-wrapper:
 :after{content:'\f0b0';display:inline-table;font-family:FontAwesome;float:right;margin:12px 10px 0px 0px;color:#999}body[fds] .mat-hint{color:#999}body[fds] .md-card-title{font-size:20px;color:#333;margin-bottom:0px}body[fds] md-card-title{padding-top:20px;padding-left:20px;padding-right:20px}body[fds] .md-card-subtitle{padding-left:20px;padding-right:20px;padding-top:10px;margin-bottom:0px}body[fds] .md-card-content{color:#666;padding:10px 20px 20px 20px;margin:0px}body[fds] .md-card .md-card-actions:last-child,body[fds] .md-card .md-card .md-card-actions:last-child{padding:0px 20px 20px 20px;margin:0px}body[fds] .fds-panel-menu-button{position:absolute;right:0px;z-index:2}body[fds] .link{color:#6B8791;font-size:14px;text-decoration:none;line-height:24px;cursor:pointer}body[fds] .link:hover{text-decoration:underline}body[fds] .link .disabled{color:#333;text-decoration:none}body[fds] .mat-sidenav-container{height:100%}.td-step-header span{display:none}body[fds] .mat-tooltip{backgrou
 nd:#666;opacity:.9;box-shadow:inset 0px 0px 3px 0px #1391c1}body[fds] .td-data-table-cell{font-size:13px;color:#666;padding:0 28px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;line-height:30px}body[fds] .td-data-table-column{color:#999;font-weight:normal}body[fds] .td-data-table-row{height:34px;border-top:1px solid #fff;border-left:1px solid #fff;border-right:1px solid #fff;border-bottom:1px solid #eee}body[fds] .td-data-table-row.selected{background-color:#eee;border:1px solid #eee}body[fds] .td-data-table-row:hover{background-color:#F8F9F9;border:1px solid #B2C1C6}body[fds] .td-data-table-cell .mat-icon-button{color:#6B8791}body[fds] .td-data-table-cell .mat-icon-button:disabled{color:#808793;cursor:not-allowed}body[fds] .td-data-table-cell .mat-button,body[fds] .td-data-table-cell .mat-icon-button,body[fds] .td-data-table-cell .mat-raised-button{height:24px;width:24px;line-height:0}body[fds] .td-data-table-cell .mat-icon-button.badge{border-top-left-radiu
 s:0px;border-top-right-radius:0px}body[fds] .td-data-table-cell .mat-icon-button.badge[disabled]{opacity:.3}body[fds] .td-data-table-column{font-size:12px;color:#999;height:34px;line-height:34px;padding:0 28px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}body[fds] .td-data-table-column .fa-caret-up,body[fds] .td-data-table-column .fa-caret-down{color:#6B8791;font-size:12px;margin-bottom:2px}body[fds] td-paging-bar{color:#999}body[fds] td-paging-bar mat-select .mat-select-value,body[fds] td-paging-bar mat-select .mat-select-arrow{color:#6B8791}body[fds] .table-title{font-size:20px;color:#333;min-width:250px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:50%;margin-right:10px}body[fds] div .td-data-table{border-bottom:2px solid #ddd;border-right:1px transparent;border-left:1px transparent}.fds-dialog-title{margin-top:0;margin-bottom:20px}body[fds] snack-bar-container{background:#FFFFFF;padding:0;box-shadow:0px 0px 3px 0px #1391c1}fds-snackbar-title ma
 t-icon.mat-icon.mat-primary.material-icons{font-size:10px;height:10px;width:10px;line-height:10px;color:#999}.fds-coaster-message{font-size:12px}.fds-snackbar-title{font-size:14px}.fds-snackbar-title i{font-size:24px}.fds-coaster-icon{position:absolute;top:24px;left:15px}.coaster-close-icon{height:10px !important;width:10px !important;line-height:10px !important;right:10px;position:absolute !important;top:10px}.fds-snackbar-wrapper{border-radius:2px;border-width:1px;border-style:solid}
+@font-face{font-family:'Roboto';font-style:normal;font-weight:300;src:local("Roboto Light"),local("Roboto-Light"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-Light.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:italic;font-weight:300;src:local("Roboto LightItalic"),local("Roboto-LightItalic"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-LightItalic.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:normal;font-weight:normal;src:local("Roboto Regular"),local("Roboto-Regular"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-Regular.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:normal;font-weight:500;src:local("Roboto Medium"),local("Roboto-Medium"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-Medium.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:normal;font-weight:bold;src:local("Roboto Bo
 ld"),local("Roboto-Bold"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-Bold.ttf") format("truetype")}@font-face{font-family:'Roboto';font-style:italic;font-weight:normal;src:local("Roboto Italic"),local("Roboto-Italic"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto/Roboto-RegularItalic.ttf") format("truetype")}@font-face{font-family:'Roboto Slab';font-style:normal;font-weight:normal;src:local("RobotoSlab Regular"),local("RobotoSlab-Regular"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto-Slab/Roboto-Slab-Regular.ttf") format("truetype")}@font-face{font-family:'Roboto Slab';font-style:normal;font-weight:bold;src:local("RobotoSlab Bold"),local("RobotoSlab-Bold"),url("../../../../../../../node_modules/roboto-fontface/fonts/Roboto-Slab/Roboto-Slab-Bold.ttf") format("truetype")}body,html{height:100%}body,button,input,label,select,td,textarea{font-family:"Roboto",sans-serif;font-size:14px}body{color:#333}strong{font-
 weight:bold}pre{overflow-x:auto}em{font-style:italic}h1,h2,h3,h4,h5,h6{font-family:"Roboto",sans-serif;font-weight:normal;font-style:normal;background:#FFFFFF}h1{color:#333}h2{color:#666}table{font-family:"Roboto",sans-serif;font-size:13px;color:#666}.camel-case{text-transform:capitalize}.header{font-family:"Roboto Medium",sans-serif;font-size:16px;color:#333;padding-bottom:10px}.help-icon{font-size:12px;color:#1491C1}.details-header{height:92px}.details-header-container{position:relative;top:22px;left:10px}.description{font-family:"Roboto Light",sans-serif;font-size:12px;color:#666}.description i{padding-right:5px}.label{font-family:"Roboto Medium",sans-serif;font-size:14px;color:#333;text-transform:uppercase}.units{font-family:"Roboto Light",sans-serif;font-size:14px;color:#333}.align-vertical{margin-top:auto;margin-bottom:auto}.align-horizontal{margin-left:auto;margin-right:auto}.fill-available-width{width:100%}.pointer{cursor:pointer}body[fds] .expansion-panel-filter-toggle-grou
 p{box-shadow:none !important}body[fds] .expansion-panel-filter-toggle-group .mat-button-toggle{height:75px;width:125px;border:1px solid #ccc}body[fds] .expansion-panel-filter-toggle-group .mat-button-toggle-label-content{height:100%;width:100%;padding:0;line-height:63px;text-align:center}body[fds] .expansion-panel-filter-toggle-group .mat-button-toggle-checked{background-color:#6B8791;color:white}body[fds] .expansion-panel-filter-toggle-group .mat-button-toggle-checked .md-display-1{color:white}body[fds] .expansion-panel-filter-toggle-group .md-display-1{color:#6B8791}body[fds] .expansion-panel-filter-toggle-group div{line-height:normal}body[fds] .tab-toggle-group{box-shadow:none !important}body[fds] .tab-toggle-group .mat-button-toggle-label-content{border-bottom:2px solid #eee}body[fds] .tab-toggle-group .mat-button-toggle-checked{background:transparent}body[fds] .tab-toggle-group .mat-button-toggle-checked .mat-button-toggle-label-content{border-bottom:2px solid #6B8791;backgroun
 d:transparent}body[fds] .on-off-toggle-group{box-shadow:none !important}body[fds] .on-off-toggle-group .mat-button-toggle{height:20px;width:35px;border:1px solid #ccc}body[fds] .on-off-toggle-group .mat-button-toggle-label-content{height:100%;width:100%;padding:0;line-height:20px;text-align:center}body[fds] .on-off-toggle-group .mat-button-toggle-checked{background-color:#6B8791;color:white;border:1px solid #6B8791}body[fds] .off-toggle.mat-button-toggle-checked{background-color:#ccc;color:#333;border:1px solid #ccc}body[fds] .mat-checkbox-inner-container{height:10px !important;width:10px !important}body[fds] .mat-checkbox-frame{height:10px;width:10px;border-color:#ddd}body[fds] .mat-checkbox-ripple{left:-7px;top:-7px;right:-7px;bottom:-7px}body[fds] .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background,body[fds] .mat-checkbox-checked.mat-accent .mat-checkbox-background{background-color:#6B8791}body[fds] .mat-checkbox-inner-container:hover{background-color:#6B8791;border-r
 adius:2px}body[fds] .mat-checkbox-background{height:10px;width:10px}body[fds] .mat-pseudo-checkbox{height:10px !important;width:10px !important;border:1px solid #ddd}body[fds] .mat-pseudo-checkbox:hover{background-color:#6B8791;border:1px solid #6B8791}body[fds] .mat-pseudo-checkbox-checked::after{content:'\f00c';font-size:8px;font-family:fontawesome;margin-top:-9px;margin-left:-1px;border:none;transform:initial}body[fds] .mat-pseudo-checkbox-checked,body[fds] .mat-pseudo-checkbox-indeterminate{background-color:#6B8791;border:1px solid #6B8791;height:10px;width:10px}body[fds] .mat-checkbox-disabled{cursor:not-allowed}body[fds] .mat-radio-container{height:12px;width:12px}body[fds] .mat-radio-outer-circle{height:12px;width:12px;background-color:#FFFFFF;border:1px solid #ddd}body[fds] .mat-radio-outer-circle:hover{background-color:#6B8791;border-color:#6B8791}body[fds] .mat-radio-checked .mat-radio-outer-circle{border:1px solid #6B8791;background-color:#6B8791}body[fds] .mat-radio-butt
 on.mat-accent.mat-radio-checked .mat-radio-outer-circle{border-color:#6B8791}body[fds] .mat-radio-inner-circle{height:10px;width:10px;left:1px;top:1px;background-color:#FFFFFF}body[fds] .mat-radio-checked .mat-radio-inner-circle{background-color:#FFFFFF}body[fds] .mat-chip{border-radius:2px;font-size:10px;font-family:"Roboto",sans-serif;font-style:normal;font-weight:normal;padding:4px 12px 4px 12px}body[fds] .mat-chip i{margin-left:10px;float:right;margin-top:2px}body[fds] .mat-basic-chip{color:#666;height:24px;margin:22px 8px 0 0}body[fds] .mat-basic-chip.td-chip-after-pad{padding:4px 12px 4px 12px}body[fds] .mat-basic-chip i{margin-left:10px;float:right;margin-top:2px}body[fds] .mat-basic-chip .td-chip{font-size:10px;min-height:unset;line-height:20px;position:relative;top:-2px}body[fds] .td-chip span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:65px}body[fds] .td-chip-disabled .td-chip{padding:0px 0px 0px 12px}body[fds] .mat-basic-chip mat-icon.td-chip-removal{f
 ont-size:15px;margin-bottom:7px}body[fds] .mat-dialog-container{padding:20px;width:400px}body[fds] .mat-tab-label{line-height:72px;text-transform:uppercase;color:#666}body[fds] .mat-tab-label:hover:not([disabled]){color:#333}body[fds] .mat-tab-label:focus:not([disabled]){background-color:#FFFFFF}body[fds] .mat-tab-label-active{color:#333}body[fds] .mat-tab-nav-bar,body[fds] .mat-tab-header{border-bottom:0px}body[fds] .mat-input-container{min-width:200px}body[fds] .mat-input-wrapper{margin:0;padding-bottom:0}body[fds] input.mat-input-element,body[fds] textarea.mat-input-element{border-radius:2px;color:#666;border:1px solid #CFD3D7;height:32px;padding:0px 10px;width:calc(100% - 26px)}body[fds] textarea.mat-input-element{padding:10px 10px}body[fds] input.mat-input-element[disabled],body[fds] textarea.mat-input-element[disabled]{background:#b2b8c1;color:#dbdee2;border:1px solid #b2b8c1}body[fds] .mat-input-subscript-wrapper{margin-top:18px;width:calc(100% - 23px)}body[fds] input.mat-inp
 ut-element:focus,body[fds] textarea.mat-input-element:focus{border-color:#6B8791}body[fds] .mat-input-underline{display:none}body[fds] .mat-input-placeholder{font-size:14px;color:#999;font-weight:300}body[fds] .mat-input-placeholder{top:29px;left:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:calc(100% - 44px)}body[fds] mat-input-container.mat-focused .mat-input-placeholder{transform:translateY(-26px) translateX(-10px) scale(0.75)}body[fds] .mat-form-field-can-float.mat-form-field-should-float .mat-form-field-placeholder{transform:translateY(-26px) translateX(-10px) scale(0.75)}body[fds] .mat-form-field-can-float .mat-form-field-autofill-control:-webkit-autofill+.mat-form-field-placeholder-wrapper .mat-form-field-placeholder{transform:translateY(-26px) translateX(-10px) scale(0.75)}body[fds] .input-button{top:5px;left:-4px;border-left:none !important}body[fds] .input-button.mat-raised-button[disabled]{opacity:1}body[fds] td-chips .mat-input-placeholder-wrapper:
 :after{content:'\f0b0';display:inline-table;font-family:FontAwesome;float:right;margin:12px 10px 0px 0px;color:#999}body[fds] .mat-hint{color:#999}body[fds] .md-card-title{font-size:20px;color:#333;margin-bottom:0px}body[fds] md-card-title{padding-top:20px;padding-left:20px;padding-right:20px}body[fds] .md-card-subtitle{padding-left:20px;padding-right:20px;padding-top:10px;margin-bottom:0px}body[fds] .md-card-content{color:#666;padding:10px 20px 20px 20px;margin:0px}body[fds] .md-card .md-card-actions:last-child,body[fds] .md-card .md-card .md-card-actions:last-child{padding:0px 20px 20px 20px;margin:0px}body[fds] .fds-panel-menu-button{position:absolute;right:0px;z-index:2}body[fds] .mat-progress-bar-buffer{background-color:#ccc}body[fds] .link{color:#6B8791;font-size:14px;text-decoration:none;line-height:24px;cursor:pointer}body[fds] .link:hover{text-decoration:underline}body[fds] .link .disabled{color:#333;text-decoration:none}body[fds] .mat-sidenav-container{height:100%}.td-step
 -header span{display:none}body[fds] .mat-tooltip{background:#666;opacity:.9;box-shadow:inset 0px 0px 3px 0px #1391c1}body[fds] .td-data-table-cell{font-size:13px;color:#666;padding:0 28px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:100%;line-height:30px}body[fds] .td-data-table-column{color:#999;font-weight:normal}body[fds] .td-data-table-row{height:34px;border-top:1px solid #fff;border-left:1px solid #fff;border-right:1px solid #fff;border-bottom:1px solid #eee}body[fds] .td-data-table-row.selected{background-color:#eee;border:1px solid #eee}body[fds] .td-data-table-row:hover{background-color:#F8F9F9;border:1px solid #B2C1C6}body[fds] .td-data-table-cell .mat-icon-button{color:#6B8791}body[fds] .td-data-table-cell .mat-icon-button:disabled{color:#808793;cursor:not-allowed}body[fds] .td-data-table-cell .mat-button,body[fds] .td-data-table-cell .mat-icon-button,body[fds] .td-data-table-cell .mat-raised-button{height:24px;width:24px;line-height:0}body[fds] .td-dat
 a-table-cell .mat-icon-button.badge{border-top-left-radius:0px;border-top-right-radius:0px}body[fds] .td-data-table-cell .mat-icon-button.badge[disabled]{opacity:.3}body[fds] .td-data-table-column{font-size:12px;color:#999;height:34px;line-height:34px;padding:0 28px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}body[fds] .td-data-table-column .fa-caret-up,body[fds] .td-data-table-column .fa-caret-down{color:#6B8791;font-size:12px;margin-bottom:2px}body[fds] td-paging-bar{color:#999}body[fds] td-paging-bar mat-select .mat-select-value,body[fds] td-paging-bar mat-select .mat-select-arrow{color:#6B8791}body[fds] .table-title{font-size:20px;color:#333;min-width:250px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:50%;margin-right:10px}body[fds] div .td-data-table{border-bottom:2px solid #ddd;border-right:1px transparent;border-left:1px transparent}.fds-dialog-title{margin-top:0;margin-bottom:20px}body[fds] snack-bar-container{background:#FFFFFF;padding:0
 ;box-shadow:0px 0px 3px 0px #1391c1}fds-snackbar-title mat-icon.mat-icon.mat-primary.material-icons{font-size:10px;height:10px;width:10px;line-height:10px;color:#999}.fds-coaster-message{font-size:12px}.fds-snackbar-title{font-size:14px}.fds-snackbar-title i{font-size:24px}.fds-coaster-icon{position:absolute;top:24px;left:15px}.coaster-close-icon{height:10px !important;width:10px !important;line-height:10px !important;right:10px;position:absolute !important;top:10px}.fds-snackbar-wrapper{border-radius:2px;border-width:1px;border-style:solid}
 
 /*# sourceMappingURL=fluid-design-system.min.css.map */
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/nifi-fds/blob/8b49e224/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css.gz
----------------------------------------------------------------------
diff --git a/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css.gz b/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css.gz
index 8a40d5a..b878c9b 100644
Binary files a/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css.gz and b/node_modules/nifi-fds/platform/core/common/styles/css/fluid-design-system.min.css.gz differ