          # Override this for custom arguments
          return parser
  
      def process_arguments(self, arguments):
          self.arguments = arguments
  
          # Setting default argument values that cannot be set by argparse
  
          # Set output dir to the same value as input dir
          # if the user didn't specify it.
 
</s> remove         if self.arguments.output_dir.lower() == "__default":
            self.arguments.output_dir = self.arguments.input_dir
 </s> add         if self.args.output_dir.lower() == "--default":
            self.args.output_dir = self.args.input_dir </s> remove         # Override this for custom arguments
 </s> add         for option in self.optional_arguments:
            args = option['opts']
            kwargs = {key: option[key] for key in option.keys() if key != 'opts'}
            parser.add_argument(*args, **kwargs) </s> remove         if self.arguments.log_changes:
 </s> add         if self.args.log_changes: </s> remove                 optlist.extend((opt, optval))
        sys.argv = optlist
        process = Thread(target=self.launch_faceswap, args=(self.command,))
        process.start()

    def launch_faceswap(self, command):
        ''' Launch the script inside a subprocess to keep the GUI active '''
        self.statustext.set('Executing: ' + command.title())
 </s> add                 self.args.extend((opt, optval))

    def execute_script(self):
        """ Execute the requested Faceswap Script """
        kwargs = {'stdout': PIPE,
                  'stderr': PIPE,
                  'bufsize': 1,
                  'universal_newlines': True}
        if os.name == 'nt':
            kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
        self.process = Popen(self.args, **kwargs)
        self.thread_stdout()
        self.thread_stderr()

    def read_stdout(self):
        """ Read stdout from the subprocess. If training, pass the loss
        values to Queue """
        while True:
            output = self.process.stdout.readline()
            if output == '' and self.process.poll() is not None:
                break
            if output:
                if self.command == 'train' and str.startswith(output, '['):
                    self.capture_loss(output)
                print(output.strip())
        returncode = self.process.poll()
        self.utils.runningtask = False
        self.utils.change_action_button()
        self.set_final_status(returncode)
        print('Process exited.')

    def read_stderr(self):
        """ Read stdout from the subprocess. If training, pass the loss
        values to Queue """
        while True:
            output = self.process.stderr.readline()
            if output == '' and self.process.poll() is not None:
                break
            print(output.strip(), file=sys.stderr)

    def thread_stdout(self):
        """ Put the subprocess stdout so that it can be read without
        blocking """
        thread = Thread(target=self.read_stdout)
        thread.daemon = True
        thread.start()

    def thread_stderr(self):
        """ Put the subprocess stderr so that it can be read without
        blocking """
        thread = Thread(target=self.read_stderr)
        thread.daemon = True
        thread.start()

    def capture_loss(self, string):
        """ Capture loss values from stdout """
        #TODO: Remove this hideous hacky fix. When the subprocess is terminated and
        # the loss dictionary is reset, 1 set of loss values ALWAYS slips through
        # and appends to the lossdict AFTER the subprocess has closed meaning that
        # checks on whether the dictionary is empty fail.
        # Therefore if the size of current loss dictionary is smaller than the
        # previous loss dictionary, assume that the process has been terminated
        # and reset it.
        # I have tried and failed to empty the subprocess stdout with:
        #   sys.exit() on the stdout/err threads (no effect)
        #   sys.stdout/stderr.flush (no effect)
        #   thread.join (locks the whole process up, because the stdout thread
        #       stubbonly refuses to release it's last line)

        currentlenloss = len(self.utils.lossdict)
        if self.lenloss > currentlenloss:
            self.utils.lossdict = dict()
            self.lenloss = 0
            return
        self.lenloss = currentlenloss

        loss = re.findall(r'([a-zA-Z_]+):.*?(\d+\.\d+)', string)

        if len(loss) < 2:
            return

        if not self.utils.lossdict:
            self.utils.lossdict.update((item[0], []) for item in loss)

        for item in loss:
            self.utils.lossdict[item[0]].append(float(item[1]))

    def terminate(self):
        """ Terminate the subprocess """
        if self.command == 'train':
            print('Sending Exit Signal', flush=True)
            try:
                now = time()
                if os.name == 'nt':
                    os.kill(self.process.pid, signal.CTRL_BREAK_EVENT)
                else:
                    self.process.send_signal(signal.SIGINT)
                while True:
                    timeelapsed = time() - now
                    if self.process.poll() is not None:
                        break
                    if timeelapsed > 30:
                        raise ValueError('Timeout reached sending Exit Signal')
                return
            except ValueError as err:
                print(err)
        print('Terminating Process...')
        self.args = arguments
          # Override this for custom arguments
          return parser
  
      def process_arguments(self, arguments):
        self.args = arguments
  
          # Setting default argument values that cannot be set by argparse
  
          # Set output dir to the same value as input dir
          # if the user didn't specify it.
keep keep keep keep replace keep keep keep keep keep
 GUI v0.2.1b (#352)

* Code refactor

* Console Added

* Add graphing with matplotlib

* Add GUI preview support

* Improve import handling.

* Add GUI integration for tools.py (Launch tools.py with the gui command)

* Reformat to conform to PEP8.

* Add Tooltips, 

* Make panels user adjustable

* Fix convert.py Sharpen default value 
tools/sort.py