text:
/******************************************************************************
  This source file is part of the Avogadro project.
  This source code is released under the 3-Clause BSD License, (see "LICENSE").
******************************************************************************/

#include "interfacescript.h"

#include <avogadro/core/coordinateblockgenerator.h>
#include <avogadro/core/molecule.h>

#include <avogadro/io/fileformat.h>
#include <avogadro/io/fileformatmanager.h>

#include <avogadro/qtgui/generichighlighter.h>
#include <avogadro/qtgui/molecule.h>
#include <avogadro/qtgui/pythonscript.h>
#include <avogadro/qtgui/rwmolecule.h>

#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>

namespace Avogadro::QtGui {

using QtGui::GenericHighlighter;
using QtGui::PythonScript;

InterfaceScript::InterfaceScript(const QString& scriptFilePath_,
                                 QObject* parent_)
  : QObject(parent_), m_interpreter(new PythonScript(scriptFilePath_, this)),
    m_moleculeExtension(QStringLiteral("Unknown"))
{}

InterfaceScript::InterfaceScript(QObject* parent_)
  : QObject(parent_), m_interpreter(new PythonScript(this)),
    m_moleculeExtension(QStringLiteral("Unknown"))
{}

InterfaceScript::~InterfaceScript() {}

bool InterfaceScript::debug() const
{
  return m_interpreter->debug();
}

QJsonObject InterfaceScript::options() const
{
  m_errors.clear();
  if (m_options.isEmpty()) {
    qDeleteAll(m_highlightStyles.values());
    m_highlightStyles.clear();

    // Retrieve/set options
    QByteArray json = m_interpreter->execute(
      QStringList() << QStringLiteral("--print-options"));

    if (m_interpreter->hasErrors()) {
      m_errors << m_interpreter->errorList();
      return m_options;
    }

    QJsonDocument doc;
    if (!parseJson(json, doc))
      return m_options;

    if (!doc.isObject()) {
      m_errors << tr("script --print-options output must be an JSON object "
                     "at top level. Received:\n%1")
                    .arg(json.constData());
      return m_options;
    }

    m_options = doc.object();

    if (m_options.contains(QStringLiteral("highlightStyles")) &&
        m_options.value(QStringLiteral("highlightStyles")).isArray()) {
      if (!parseHighlightStyles(
            m_options.value(QStringLiteral("highlightStyles")).toArray())) {
        qDebug() << "Failed to parse highlighting styles.";
      }
    }
  }

  // Check if the generator needs to read a molecule.
  m_moleculeExtension = QLatin1String("cjson");
  if (m_options.contains(QStringLiteral("inputMoleculeFormat")) &&
      m_options[QStringLiteral("inputMoleculeFormat")].isString()) {
    m_moleculeExtension =
      m_options[QStringLiteral("inputMoleculeFormat")].toString();
  }

  return m_options;
}

QString InterfaceScript::displayName() const
{
  m_errors.clear();
  if (m_displayName.isEmpty()) {
    m_displayName = QString(m_interpreter->execute(
      QStringList() << QStringLiteral("--display-name")));
    m_errors << m_interpreter->errorList();
    m_displayName = m_displayName.trimmed();
  }

  return m_displayName;
}

QString InterfaceScript::menuPath() const
{
  m_errors.clear();
  if (m_menuPath.isEmpty()) {
    m_menuPath = QString(
      m_interpreter->execute(QStringList() << QStringLiteral("--menu-path")));
    m_errors << m_interpreter->errorList();
    m_menuPath = m_menuPath.trimmed();
  }

  return m_menuPath;
}

QString InterfaceScript::scriptFilePath() const
{
  return m_interpreter->scriptFilePath();
}

void InterfaceScript::setScriptFilePath(const QString& scriptFile)
{
  reset();
  m_interpreter->setScriptFilePath(scriptFile);
}

void InterfaceScript::reset()
{
  m_interpreter->setDefaultPythonInterpretor();
  m_interpreter->setScriptFilePath(QString());
  m_moleculeExtension = QLatin1String("Unknown");
  m_displayName = QString();
  m_options = QJsonObject();
  m_warnings.clear();
  m_errors.clear();
  m_filenames.clear();
  m_mainFileName.clear();
  m_files.clear();
  m_fileHighlighters.clear();
  m_highlightStyles.clear();
}

bool InterfaceScript::runCommand(const QJsonObject& options_,
                                 Core::Molecule* mol)
{
  m_errors.clear();
  m_warnings.clear();
  m_filenames.clear();
  qDeleteAll(m_fileHighlighters.values());
  m_fileHighlighters.clear();
  m_mainFileName.clear();
  m_files.clear();

  // Add the molecule file to the options
  QJsonObject allOptions(options_);
  if (!insertMolecule(allOptions, *mol))
    return false;

  connect(m_interpreter, &PythonScript::finished, this, &::Avogadro::QtGui::InterfaceScript::commandFinished);
  m_interpreter->asyncExecute(QStringList() << QStringLiteral("--run-command"),
                              QJsonDocument(allOptions).toJson());
  return true;
}

void InterfaceScript::commandFinished()
{
  emit finished();
}

bool InterfaceScript::processCommand(Core::Molecule* mol)
{
  if (m_interpreter == nullptr)
    return false;

  QByteArray json(m_interpreter->asyncResponse());

  if (m_interpreter->hasErrors()) {
    m_errors << m_interpreter->errorList();
    return false;
  }

  QJsonDocument doc;
  if (!parseJson(json, doc)) {
    return false;
  }

  // Update cache
  bool result = true;
  if (doc.isObject()) {
    QJsonObject obj = doc.object();

    // Check for any warnings:
    if (obj.contains(QStringLiteral("warnings"))) {
      if (obj[QStringLiteral("warnings")].isArray()) {
        foreach (const QJsonValue& warning, obj["warnings"].toArray()) {
          if (warning.isString())
            m_warnings << warning.toString();
          else
            m_errors << tr("Non-string warning returned.");
        }
      } else {
        m_errors << tr("'warnings' member is not an array.");
      }
    }

    m_moleculeExtension = "cjson";
    if (obj.contains("moleculeFormat") && obj["moleculeFormat"].isString()) {
      m_moleculeExtension = obj["moleculeFormat"].toString();
    }

    Io::FileFormatManager& formats = Io::FileFormatManager::instance();
    QScopedPointer<Io::FileFormat> format(
      formats.newFormatFromFileExtension(m_moleculeExtension.toStdString()));

    if (format.isNull()) {
      m_errors << tr("Error reading molecule representation: "
                     "Unrecognized file format: %1")
                    .arg(m_moleculeExtension);
      return false;
    }

    auto* guiMol = static_cast<QtGui::Molecule*>(mol);
    QtGui::Molecule newMol(guiMol->parent());
    if (m_moleculeExtension == "cjson") {
      // convert the "cjson" field to a string
      QJsonObject cjsonObj = obj["cjson"].toObject();
      QJsonDocument doc(cjsonObj);
      QString strCJSON(doc.toJson(QJsonDocument::Compact));
      if (!strCJSON.isEmpty()) {
        result = format->readString(strCJSON.toStdString(), newMol);
      }
    } else if (obj.contains(m_moleculeExtension) &&
               obj[m_moleculeExtension].isString()) {
      QString strFile = obj[m_moleculeExtension].toString();
      result = format->readString(strFile.toStdString(), newMol);
    }

    // check if the script wants us to perceive bonds first
    if (obj["bond"].toBool()) {
      newMol.perceiveBondsSimple();
    }

    if (obj["append"].toBool()) { // just append some new bits
      guiMol->undoMolecule()->appendMolecule(newMol, m_displayName);
    } else { // replace the whole molecule
      Molecule::MoleculeChanges changes = (Molecule::Atoms | Molecule::Bonds |
                                           Molecule::Added | Molecule::Removed);
      guiMol->undoMolecule()->modifyMolecule(newMol, changes, m_displayName);
    }
  }
  return result;
}

bool InterfaceScript::generateInput(const QJsonObject& options_,
                                    const Core::Molecule& mol)
{
  m_errors.clear();
  m_warnings.clear();
  m_filenames.clear();
  qDeleteAll(m_fileHighlighters.values());
  m_fileHighlighters.clear();
  m_mainFileName.clear();
  m_files.clear();

  // Add the molecule file to the options
  QJsonObject allOptions(options_);
  if (!insertMolecule(allOptions, mol))
    return false;

  QByteArray json(
    m_interpreter->execute(QStringList() << QStringLiteral("--generate-input"),
                           QJsonDocument(allOptions).toJson()));

  if (m_interpreter->hasErrors()) {
    m_errors << m_interpreter->errorList();
    return false;
  }

  QJsonDocument doc;
  if (!parseJson(json, doc))
    return false;

  // Update cache
  bool result = true;
  if (doc.isObject()) {
    QJsonObject obj = doc.object();

    // Check for any warnings:
    if (obj.contains(QStringLiteral("warnings"))) {
      if (obj[QStringLiteral("warnings")].isArray()) {
        foreach (const QJsonValue& warning, obj["warnings"].toArray()) {
          if (warning.isString())
            m_warnings << warning.toString();
          else
            m_errors << tr("Non-string warning returned.");
        }
      } else {
        m_errors << tr("'warnings' member is not an array.");
      }
    }

    // Extract input file text:
    if (obj.contains(QStringLiteral("files"))) {
      if (obj[QStringLiteral("files")].isArray()) {
        foreach (const QJsonValue& file, obj["files"].toArray()) {
          if (file.isObject()) {
            QJsonObject fileObj = file.toObject();
            if (fileObj[QStringLiteral("filename")].isString()) {
              QString fileName = fileObj[QStringLiteral("filename")].toString();
              QString contents;
              if (fileObj[QStringLiteral("contents")].isString()) {
                contents = fileObj[QStringLiteral("contents")].toString();
              } else if (fileObj[QStringLiteral("filePath")].isString()) {
                QFile refFile(fileObj[QStringLiteral("filePath")].toString());
                if (refFile.exists() && refFile.open(QFile::ReadOnly)) {
                  contents = QString(refFile.readAll());
                } else {
                  contents = tr("Reference file '%1' does not exist.")
                               .arg(refFile.fileName());
                  m_warnings << tr("Error populating file %1: %2")
                                  .arg(fileName, contents);
                }
              } else {
                m_errors << tr("File '%1' poorly formed. Missing string "
                               "'contents' or 'filePath' members.")
                              .arg(fileName);
                contents = m_errors.back();
                result = false;
              }
              replaceKeywords(contents, mol);
              m_filenames << fileName;
              m_files.insert(fileObj[QStringLiteral("filename")].toString(),
                             contents);

              // Concatenate the requested styles for this input file.
              if (fileObj[QStringLiteral("highlightStyles")].isArray()) {
                auto* highlighter(new GenericHighlighter(this));
                foreach (const QJsonValue& styleVal,
                         fileObj["highlightStyles"].toArray()) {
                  if (styleVal.isString()) {
                    QString styleName(styleVal.toString());
                    if (m_highlightStyles.contains(styleName)) {
                      *highlighter += *m_highlightStyles[styleName];
                    } else {
                      qDebug() << "Cannot find highlight style '" << styleName
                               << "' for file '" << fileName << "'";
                    }
                  }
                }
                if (highlighter->ruleCount() > 0)
                  m_fileHighlighters[fileName] = highlighter;
                else
                  highlighter->deleteLater();
              }
            } else {
              result = false;
              m_errors << tr("Malformed file entry: filename/contents missing"
                             " or not strings:\n%1")
                            .arg(QString(QJsonDocument(fileObj).toJson()));
            } // end if/else filename and contents are strings
          } else {
            result = false;
            m_errors << tr("Malformed file entry at index %1: Not an object.")
                          .arg(m_filenames.size());
          } // end if/else file is JSON object
        }   // end foreach file
      } else {
        result = false;
        m_errors << tr("'files' member not an array.");
      } // end if obj["files"] is JSON array
    } else {
      result = false;
      m_errors << tr("'files' member missing.");
    } // end if obj contains "files"

    // Extract main input filename:
    if (obj.contains(QStringLiteral("mainFile"))) {
      if (obj[QStringLiteral("mainFile")].isString()) {
        QString mainFile = obj[QStringLiteral("mainFile")].toString();
        if (m_filenames.contains(mainFile)) {
          m_mainFileName = mainFile;
        } else {
          result = false;
          m_errors << tr("'mainFile' member does not refer to an entry in "
                         "'files'.");
        } // end if/else mainFile is known
      } else {
        result = false;
        m_errors << tr("'mainFile' member must be a string.");
      } // end if/else mainFile is string
    } else {
      // If no mainFile is specified and there is only one file, use it as the
      // main file. Otherwise, don't set a main input file -- all files will
      // be treated as supplemental input files
      if (m_filenames.size() == 1)
        m_mainFileName = m_filenames.first();
    } // end if/else object contains mainFile
  } else {
    result = false;
    m_errors << tr("Response must be a JSON object at top-level.");
  }

  if (result == false)
    m_errors << tr("Script output:\n%1").arg(QString(json));

  return result;
}

int InterfaceScript::numberOfInputFiles() const
{
  return m_filenames.size();
}

QStringList InterfaceScript::fileNames() const
{
  return m_filenames;
}

QString InterfaceScript::mainFileName() const
{
  return m_mainFileName;
}

QString InterfaceScript::fileContents(const QString& fileName) const
{
  return m_files.value(fileName, QString());
}

GenericHighlighter* InterfaceScript::createFileHighlighter(
  const QString& fileName) const
{
  GenericHighlighter* toClone(m_fileHighlighters.value(fileName, nullptr));
  return toClone ? new GenericHighlighter(*toClone) : toClone;
}

void InterfaceScript::setDebug(bool d)
{
  m_interpreter->setDebug(d);
}

bool InterfaceScript::parseJson(const QByteArray& json,
                                QJsonDocument& doc) const
{
  QJsonParseError error;
  doc = QJsonDocument::fromJson(json, &error);

  if (error.error != QJsonParseError::NoError) {
    m_errors << tr("Parse error at offset %L1: '%2'\nRaw JSON:\n\n%3")
                  .arg(error.offset)
                  .arg(error.errorString())
                  .arg(QString(json));
    return false;
  }
  return true;
}

bool InterfaceScript::insertMolecule(QJsonObject& json,
                                     const Core::Molecule& mol) const
{
  // Update the cached options if the format is not set
  if (m_moleculeExtension == QLatin1String("Unknown"))
    options();

  if (m_moleculeExtension == QLatin1String("None"))
    return true;

  // insert the selected atoms
  QJsonArray selectedList;
  for (Index i = 0; i < mol.atomCount(); ++i) {
    if (mol.atomSelected(i))
      selectedList.append(static_cast<qint64>(i));
  }
  json.insert("selectedatoms", selectedList);

  // insert the total charge
  json.insert("charge", mol.totalCharge());

  // insert the spin multiplicity
  json.insert("spin", mol.totalSpinMultiplicity());

  Io::FileFormatManager& formats = Io::FileFormatManager::instance();
  QScopedPointer<Io::FileFormat> format(
    formats.newFormatFromFileExtension(m_moleculeExtension.toStdString()));

  if (format.isNull()) {
    m_errors << tr("Error writing molecule representation to string: "
                   "Unrecognized file format: %1")
                  .arg(m_moleculeExtension);
    return false;
  }

  std::string str;
  if (!format->writeString(str, mol)) {
    m_errors << tr("Error writing molecule representation to string: %1")
                  .arg(QString::fromStdString(format->error()));
    return false;
  }

  if (m_moleculeExtension != QLatin1String("cjson")) {
    json.insert(m_moleculeExtension, QJsonValue(QString::fromStdString(str)));
  } else {
    // If cjson was requested, embed the actual JSON, rather than the string.
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(str.c_str(), &error);
    if (error.error != QJsonParseError::NoError) {
      m_errors << tr("Error generating cjson object: Parse error at offset %1: "
                     "%2\nRaw JSON:\n\n%3")
                    .arg(error.offset)
                    .arg(error.errorString())
                    .arg(QString::fromStdString(str));
      return false;
    }

    if (!doc.isObject()) {
      m_errors << tr("Error generator cjson object: Parsed JSON is not an "
                     "object:\n%1")
                    .arg(QString::fromStdString(str));
      return false;
    }

    json.insert(m_moleculeExtension, doc.object());
  }

  return true;
}

QString InterfaceScript::generateCoordinateBlock(
  const QString& spec, const Core::Molecule& mol) const
{
  Core::CoordinateBlockGenerator gen;
  gen.setMolecule(&mol);
  gen.setSpecification(spec.toStdString());
  std::string tmp(gen.generateCoordinateBlock());
  if (!tmp.empty())
    tmp.resize(tmp.size() - 1); // Pop off the trailing newline
  return QString::fromStdString(tmp);
}

void InterfaceScript::replaceKeywords(QString& str,
                                      const Core::Molecule& mol) const
{
  // Simple keywords:
  str.replace(QLatin1String("$$atomCount$$"), QString::number(mol.atomCount()));
  str.replace(QLatin1String("$$bondCount$$"), QString::number(mol.bondCount()));

  // Find each coordinate block keyword in the file, then generate and replace
  // it with the appropriate values.
  QRegExp coordParser(R"(\$\$coords:([^\$]*)\$\$)");
  int ind = 0;
  while ((ind = coordParser.indexIn(str, ind)) != -1) {
    // Extract spec and prepare the replacement
    const QString keyword = coordParser.cap(0);
    const QString spec = coordParser.cap(1);

    // Replace all blocks with this signature
    str.replace(keyword, generateCoordinateBlock(spec, mol));

  } // end for coordinate block
}

bool InterfaceScript::parseHighlightStyles(const QJsonArray& json) const
{
  bool result(true);
  foreach (QJsonValue styleVal, json) {
    if (!styleVal.isObject()) {
      qDebug() << "Non-object in highlightStyles array.";
      result = false;
      continue;
    }
    QJsonObject styleObj(styleVal.toObject());

    if (!styleObj.contains(QStringLiteral("style"))) {
      qDebug() << "Style object missing 'style' member.";
      result = false;
      continue;
    }
    if (!styleObj.value(QStringLiteral("style")).isString()) {
      qDebug() << "Style object contains non-string 'style' member.";
      result = false;
      continue;
    }
    QString styleName(styleObj.value(QStringLiteral("style")).toString());

    if (m_highlightStyles.contains(styleName)) {
      qDebug() << "Duplicate highlight style: " << styleName;
      result = false;
      continue;
    }

    if (!styleObj.contains(QStringLiteral("rules"))) {
      qDebug() << "Style object" << styleName << "missing 'rules' member.";
      result = false;
      continue;
    }
    if (!styleObj.value(QStringLiteral("rules")).isArray()) {
      qDebug() << "Style object" << styleName
               << "contains non-array 'rules' member.";
      result = false;
      continue;
    }
    QJsonArray rulesArray(styleObj.value(QStringLiteral("rules")).toArray());

    auto* highlighter(
      new GenericHighlighter(const_cast<InterfaceScript*>(this)));
    if (!parseRules(rulesArray, *highlighter)) {
      qDebug() << "Error parsing style" << styleName << '\n'
               << QString(QJsonDocument(styleObj).toJson());
      highlighter->deleteLater();
      result = false;
      continue;
    }
    m_highlightStyles.insert(styleName, highlighter);
  }

  return result;
}

bool InterfaceScript::parseRules(const QJsonArray& json,
                                 GenericHighlighter& highligher) const
{
  bool result(true);
  foreach (QJsonValue ruleVal, json) {
    if (!ruleVal.isObject()) {
      qDebug() << "Rule is not an object.";
      result = false;
      continue;
    }
    QJsonObject ruleObj(ruleVal.toObject());

    if (!ruleObj.contains(QStringLiteral("patterns"))) {
      qDebug() << "Rule missing 'patterns' array:" << '\n'
               << QString(QJsonDocument(ruleObj).toJson());
      result = false;
      continue;
    }
    if (!ruleObj.value(QStringLiteral("patterns")).isArray()) {
      qDebug() << "Rule 'patterns' member is not an array:" << '\n'
               << QString(QJsonDocument(ruleObj).toJson());
      result = false;
      continue;
    }
    QJsonArray patternsArray(
      ruleObj.value(QStringLiteral("patterns")).toArray());

    if (!ruleObj.contains(QStringLiteral("format"))) {
      qDebug() << "Rule missing 'format' object:" << '\n'
               << QString(QJsonDocument(ruleObj).toJson());
      result = false;
      continue;
    }
    if (!ruleObj.value(QStringLiteral("format")).isObject()) {
      qDebug() << "Rule 'format' member is not an object:" << '\n'
               << QString(QJsonDocument(ruleObj).toJson());
      result = false;
      continue;
    }
    QJsonObject formatObj(ruleObj.value(QStringLiteral("format")).toObject());

    GenericHighlighter::Rule& rule = highligher.addRule();

    foreach (QJsonValue patternVal, patternsArray) {
      QRegExp pattern;
      if (!parsePattern(patternVal, pattern)) {
        qDebug() << "Error while parsing pattern:" << '\n'
                 << QString(QJsonDocument(patternVal.toObject()).toJson());
        result = false;
        continue;
      }
      rule.addPattern(pattern);
    }

    QTextCharFormat format;
    if (!parseFormat(formatObj, format)) {
      qDebug() << "Error while parsing format:" << '\n'
               << QString(QJsonDocument(formatObj).toJson());
      result = false;
    }
    rule.setFormat(format);
  }

  return result;
}

bool InterfaceScript::parseFormat(const QJsonObject& json,
                                  QTextCharFormat& format) const
{
  // Check for presets first:
  if (json.contains(QStringLiteral("preset"))) {
    if (!json[QStringLiteral("preset")].isString()) {
      qDebug() << "Preset is not a string.";
      return false;
    }

    QString preset(json[QStringLiteral("preset")].toString());
    /// @todo Store presets in a singleton that can be configured in the GUI,
    /// rather than hardcoding them.
    if (preset == QLatin1String("title")) {
      format.setFontFamily(QStringLiteral("serif"));
      format.setForeground(Qt::darkGreen);
      format.setFontWeight(QFont::Bold);
    } else if (preset == QLatin1String("keyword")) {
      format.setFontFamily(QStringLiteral("mono"));
      format.setForeground(Qt::darkBlue);
    } else if (preset == QLatin1String("property")) {
      format.setFontFamily(QStringLiteral("mono"));
      format.setForeground(Qt::darkRed);
    } else if (preset == QLatin1String("literal")) {
      format.setFontFamily(QStringLiteral("mono"));
      format.setForeground(Qt::darkMagenta);
    } else if (preset == QLatin1String("comment")) {
      format.setFontFamily(QStringLiteral("serif"));
      format.setForeground(Qt::darkGreen);
      format.setFontItalic(true);
    } else {
      qDebug() << "Invalid style preset: " << preset;
      return false;
    }
    return true;
  }

  // Extract an RGB tuple from 'array' as a QBrush:
  struct
  {
    QBrush operator()(const QJsonArray& array, bool* ok)
    {
      *ok = false;
      QBrush result;

      if (array.size() != 3)
        return result;

      int rgb[3];
      for (int i = 0; i < 3; ++i) {
        if (!array.at(i).isDouble())
          return result;
        rgb[i] = static_cast<int>(array.at(i).toDouble());
        if (rgb[i] < 0 || rgb[i] > 255) {
          qDebug() << "Warning: Color component value invalid: " << rgb[i]
                   << " (Valid range is 0-255).";
        }
      }

      result.setColor(QColor(rgb[0], rgb[1], rgb[2]));
      result.setStyle(Qt::SolidPattern);
      *ok = true;
      return result;
    }
  } colorParser;

  if (json.contains(QStringLiteral("foreground")) &&
      json.value(QStringLiteral("foreground")).isArray()) {
    QJsonArray foregroundArray(
      json.value(QStringLiteral("foreground")).toArray());
    bool ok;
    format.setForeground(colorParser(foregroundArray, &ok));
    if (!ok)
      return false;
  }

  if (json.contains(QStringLiteral("background")) &&
      json.value(QStringLiteral("background")).isArray()) {
    QJsonArray backgroundArray(
      json.value(QStringLiteral("background")).toArray());
    bool ok;
    format.setBackground(colorParser(backgroundArray, &ok));
    if (!ok)
      return false;
  }

  if (json.contains(QStringLiteral("attributes")) &&
      json.value(QStringLiteral("attributes")).isArray()) {
    QJsonArray attributesArray(
      json.value(QStringLiteral("attributes")).toArray());
    format.setFontWeight(attributesArray.contains(QLatin1String("bold"))
                           ? QFont::Bold
                           : QFont::Normal);
    format.setFontItalic(attributesArray.contains(QLatin1String("italic")));
    format.setFontUnderline(
      attributesArray.contains(QLatin1String("underline")));
  }

  if (json.contains(QStringLiteral("family")) &&
      json.value(QStringLiteral("family")).isString()) {
    format.setFontFamily(json.value(QStringLiteral("family")).toString());
  }

  return true;
}

bool InterfaceScript::parsePattern(const QJsonValue& json,
                                   QRegExp& pattern) const
{
  if (!json.isObject())
    return false;

  QJsonObject patternObj(json.toObject());

  if (patternObj.contains(QStringLiteral("regexp")) &&
      patternObj.value(QStringLiteral("regexp")).isString()) {
    pattern.setPatternSyntax(QRegExp::RegExp2);
    pattern.setPattern(patternObj.value(QStringLiteral("regexp")).toString());
  } else if (patternObj.contains(QStringLiteral("wildcard")) &&
             patternObj.value(QStringLiteral("wildcard")).isString()) {
    pattern.setPatternSyntax(QRegExp::WildcardUnix);
    pattern.setPattern(patternObj.value(QStringLiteral("wildcard")).toString());
  } else if (patternObj.contains(QStringLiteral("string")) &&
             patternObj.value(QStringLiteral("string")).isString()) {
    pattern.setPatternSyntax(QRegExp::FixedString);
    pattern.setPattern(patternObj.value(QStringLiteral("string")).toString());
  } else {
    return false;
  }

  if (patternObj.contains(QStringLiteral("caseSensitive"))) {
    pattern.setCaseSensitivity(
      patternObj.value(QStringLiteral("caseSensitive")).toBool(true)
        ? Qt::CaseSensitive
        : Qt::CaseInsensitive);
  }

  return true;
}

} // namespace Avogadro


text:
<!DOCTYPE html>
<html lang="">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
</head>

<body>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
    <script src="../release/mistral.js"></script>
    <script>
        var view = {
            title: "Joe",
            calc: function() {
                return 2 + 4;
            }
        };

        var output = Mistral.render("{{title}} spends {{calc}}", view);
        console.log(output);

    </script>

</body>

</html>

redpajama_set_name: RedPajamaGithub


text:
<?php

/**
 * @namespace
 */
namespace Solarium\QueryType\Select\Query\Component\Facet;

use Solarium\QueryType\Select\Query\Component\FacetSet;

/**
 * Facet pivot
 *
 * @link http://wiki.apache.org/solr/SimpleFacetParameters#Pivot_.28ie_Decision_Tree.29_Faceting
 */
class Pivot extends Facet
{
    /**
     * Fields to use
     *
     * @var array
     */
    protected $fields = array();

    /**
     * Initialize options
     *
     * @return void
     */
    protected function init()
    {
        if (isset($this->options['fields'])) {
            $this->addFields($this->options['fields']);
        }
    }

    /**
     * Get the facet type
     *
     * @return string
     */
    public function getType()
    {
        return FacetSet::FACET_PIVOT;
    }

    /**
     * Set the facet mincount
     *
     * @param  int  $minCount
     * @return self Provides fluent interface
     */
    public function setMinCount($minCount)
    {
        return $this->setOption('mincount', $minCount);
    }

    /**
     * Get the facet mincount
     *
     * @return int
     */
    public function getMinCount()
    {
        return $this->getOption('mincount');
    }

    /**
     * Specify a field to return in the resultset
     *
     * @param  string $field
     * @return self   Provides fluent interface
     */
    public function addField($field)
    {
        $field = trim($field);
        $this->fields[$field] = true;

        return $this;
    }

    /**
     * Specify multiple fields to return in the resultset
     *
     * @param string|array $fields can be an array or string with comma
     *                             separated fieldnames
     *
     * @return self Provides fluent interface
     */
    public function addFields($fields)
    {
        if (is_string($fields)) {
            $fields = explode(',', $fields);
        }

        foreach ($fields as $field) {
            $this->addField($field);
        }

        return $this;
    }

    /**
     * Remove a field from the field list
     *
     * @param  string $field
     * @return self   Provides fluent interface
     */
    public function removeField($field)
    {
        if (isset($this->fields[$field])) {
            unset($this->fields[$field]);
        }

        return $this;
    }

    /**
     * Remove all fields from the field list.
     *
     * @return self Provides fluent interface
     */
    public function clearFields()
    {
        $this->fields = array();

        return $this;
    }

    /**
     * Get the list of fields
     *
     * @return array
     */
    public function getFields()
    {
        return array_keys($this->fields);
    }

    /**
     * Set multiple fields
     *
     * This overwrites any existing fields
     *
     * @param  array $fields
     * @return self  Provides fluent interface
     */
    public function setFields($fields)
    {
        $this->clearFields();
        $this->addFields($fields);

        return $this;
    }
}


text:
'use strict';

// Usage aggregator service.

const _ = require('underscore');
const webapp = require('abacus-webapp');
const cluster = require('abacus-cluster');
const router = require('abacus-router');
const yieldable = require('abacus-yieldable');
const urienv = require('abacus-urienv');
const seqid = require('abacus-seqid');
const oauth = require('abacus-oauth');
const mconfigcb = require('abacus-metering-config');
const rconfigcb = require('abacus-rating-config');
const timewindow = require('abacus-timewindow');

const transform = require('abacus-transform');
const dataflow = require('abacus-dataflow');
const dbclient = require('abacus-dbclient');

const filter = _.filter;
const map = _.map;
const last = _.last;
const extend = _.extend;
const rest = _.rest;
const indexOf = _.indexOf;
const object = _.object;

const treduce = yieldable(transform.reduce);

const mconfig = yieldable(mconfigcb);
const rconfig = yieldable(rconfigcb);

/* eslint camelcase: 1 */

// Setup debug log
const debug = require('abacus-debug')('abacus-usage-aggregator');

// Secure the routes or not
const secured = () => process.env.SECURED === 'true' ? true : false;

// OAuth bearer access token with Abacus system access scopes
let systemToken;

// Resolve service URIs
const uris = urienv({
  auth_server: 9882,
  sink: undefined
});

// Return OAuth system scopes needed to write input docs
const iwscope = (udoc) => secured() ? {
  system: ['abacus.usage.write']
} : undefined;

// Return OAuth system scopes needed to read input and output docs
const rscope = (udoc) => secured() ? {
  system: ['abacus.usage.read']
} : undefined;

// Return the keys and times of our docs
const ikey = (udoc) =>
  udoc.organization_id;

const itime = (udoc) =>
  seqid();

const igroups = (udoc) =>
  [udoc.organization_id,
    [udoc.organization_id, udoc.space_id, udoc.consumer_id || 'UNKNOWN']
    .join('/'),
    [udoc.organization_id, udoc.resource_instance_id,
      udoc.consumer_id || 'UNKNOWN', udoc.plan_id, udoc.metering_plan_id,
      udoc.rating_plan_id, udoc.pricing_plan_id].join('/')];

const okeys = (udoc, ikey) =>
  [udoc.organization_id,
    [udoc.organization_id, udoc.space_id, udoc.consumer_id || 'UNKNOWN']
    .join('/'),
    [udoc.organization_id, udoc.resource_instance_id,
      udoc.consumer_id || 'UNKNOWN', udoc.plan_id, udoc.metering_plan_id,
      udoc.rating_plan_id, udoc.pricing_plan_id].join('/')];

const otimes = (udoc, itime) =>
  [itime, itime, map([udoc.start, udoc.end], seqid.pad16).join('/')];

// The scaling factor of each time window for creating the date string
// [Second, Minute, Hour, Day, Month, Year, Forever]
const slack = () => /^[0-9]+[MDhms]$/.test(process.env.SLACK) ? {
  scale : process.env.SLACK.charAt(process.env.SLACK.length - 1),
  width : process.env.SLACK.match(/[0-9]+/)[0]
} : {
  scale : 'm',
  width : 10
};

// Time dimension keys corresponding to their respective window positions
const dimensions = ['s', 'm', 'h', 'D', 'M'];

// Checks if a consumer usage should be pruned from the aggregated usage
// based upon whether the current time exceeds 2 months + slack
const shouldNotPrune = (time) => {
  const d = new Date(time);
  const prunescales = [d.getUTCFullYear(), d.getUTCMonth() + 2, d.getUTCDate(),
    d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(),
    d.getUTCMilliseconds()];
  prunescales[5 - indexOf(dimensions, slack().scale)] += slack().width;
  return Date.UTC.apply(null, prunescales) > new Date().getTime();
};

// Find an element with the specified id in a list, and lazily construct and
// add a new one if no element is found
const lazyCons = (l, prop, id, cons) => {
  const f = filter(l, (e) => e[prop] === id);
  if(f.length) return f[0];
  const e = new cons(id);
  l.push(e);
  return e;
};

// Define the objects used to represent a hiearchy of aggregated usage inside
// an organization

// Represent an org, aggregated resource usage and the spaces it contains
const Org = function(id) {
  extend(this, {
    organization_id: id,
    resources: [],
    spaces: [],
    resource_instances: []
  });
};
const newOrg = function(id) {
  return new Org(id);
};
Org.prototype.resource = function(id) {
  return lazyCons(this.resources, 'resource_id', id, Org.Resource);
};
Org.prototype.space = function(id) {
  return lazyCons(this.spaces, 'space_id', id, Org.Space);
};

// Represent a space, aggregated resource usage and the consumers it contains
Org.Space = function(id) {
  extend(this, {
    space_id: id,
    resources: [],
    consumers: []
  });
};
Org.Space.prototype.resource = function(id) {
  return lazyCons(this.resources, 'resource_id', id, Org.Resource);
};
Org.Space.prototype.consumer = function(id, space_id, processed, doc_id) {
  // Construct or retrieve the consumer object
  const consumer = lazyCons(this.consumers, 'consumer_id', id, Org.Consumer);
  consumer.processed = processed;
  consumer.doc_id = doc_id;
  consumer.space_id = space_id;

  // Filter out any pruneable consumers
  this.consumers = filter(this.consumers, (c) => shouldNotPrune(c.processed));
};

// Represent a resource instance reference
Org.ResourceInstance = function(key) {
  extend(this, {
    key: key
  });
};
Org.prototype.resource_instance = function(key, time, processed) {
  const instance = lazyCons(this.resource_instances, 'key', key,
    Org.ResourceInstance);
  instance.id = dbclient.kturi(key, time);
  instance.processed = processed;
  this.resource_instances = filter(this.resource_instances,
    (ri) => shouldNotPrune(ri.processed));
  return instance;
};

// Represent a consumer reference
Org.Consumer = function(id) {
  extend(this, {
    consumer_id: id
  });
};

// Represent a consumer and aggregated resource usage
const Consumer = function(id) {
  extend(this, {
    consumer_id: id,
    resources: []
  });
};
const newConsumer = function(id) {
  return new Consumer(id);
};
Consumer.prototype.resource = function(id) {
  return lazyCons(this.resources, 'resource_id', id, Org.Resource);
};

// Represent a resource and its aggregated metric usage
Org.Resource = function(id) {
  extend(this, {
    resource_id: id,
    plans: [],
    aggregated_usage: []
  });
};
Org.Resource.prototype.plan = function(id) {
  return lazyCons(this.plans, 'plan_id', id, Org.Plan);
};
Org.Resource.prototype.metric = function(metric) {
  return lazyCons(this.aggregated_usage, 'metric', metric, Org.Metric);
};

// Represent a plan and its aggregated metric usage
Org.Plan = function(id) {
  extend(this, {
    plan_id: id,
    aggregated_usage: []
  }, object(
    ['metering_plan_id', 'rating_plan_id', 'pricing_plan_id'],
    rest(id.split('/'))
  ));
};
Org.Plan.prototype.metric = function(metric) {
  return lazyCons(this.aggregated_usage, 'metric', metric, Org.Metric);
};

// Represent a metric based aggregation windows
Org.Metric = function(metric) {
  extend(this, {
    metric: metric,
    windows: [
      [null],
      [null],
      [null],
      [null],
      [null]
    ]
  });
};

// Revive an org object
const reviveOrg = (org) => {
  org.resource = Org.prototype.resource;
  org.space = Org.prototype.space;
  org.resource_instance = Org.prototype.resource_instance;
  map(org.resources, (s) => {
    s.plan = Org.Resource.prototype.plan;
    s.metric = Org.Resource.prototype.metric;
    map(s.plans, (s) => {
      s.metric = Org.Plan.prototype.metric;
    });
  });
  map(org.spaces, (s) => {
    s.resource = Org.Space.prototype.resource;
    s.consumer = Org.Space.prototype.consumer;
    map(s.resources, (r) => {
      r.plan = Org.Resource.prototype.plan;
      r.metric = Org.Resource.prototype.metric;
      map(r.plans, (p) => {
        p.metric = Org.Plan.prototype.metric;
      });
    });
  });
  return org;
};

// Revive a consumer object
const reviveCon = (con) => {
  con.resource = Consumer.prototype.resource;
  map(con.resources, (r) => {
    r.plan = Org.Resource.prototype.plan;
    r.metric = Org.Resource.prototype.metric;
    map(r.plans, (p) => {
      p.metric = Org.Plan.prototype.metric;
    });
  });
  return con;
};

// Return the configured price for the metrics that is attached in the
// usage document
const price = (pricings, metric) =>
  filter(pricings, (m) => m.name === metric)[0].price;

// Return the rate function for a given metric
const ratefn = (metrics, metric) => {
  return filter(metrics, (m) => m.name === metric)[0].ratefn;
};

// Return the aggregate function for a given metric
const aggrfn = (metrics, metric) => {
  return filter(metrics, (m) => m.name === metric)[0].aggregatefn;
};

// Shifts a single resource's aggregated usage
const shiftResources = (resources, oldend, newend) => {
  const shiftAggregatedUsage = (aggregated) => {
    map(aggregated, (au) => {
      map(au.windows, (w, i) => {
        timewindow.shiftWindow(oldend, newend, w, dimensions[i]);
      });
    });
  };

  // Shift both the resource aggregated usage and plan aggregated usage
  map(resources, (resource) => {
    shiftAggregatedUsage(resource.aggregated_usage);
    map(resource.plans, (plan) => {
      shiftAggregatedUsage(plan.aggregated_usage);
    });
  });
};

// Shift an aggregated usage object
const shift = (newa, a, processed) => {
  if(a && a.processed && processed - (a ? a.processed : 0) >= 0) {
    const oldend = new Date(a.processed);
    const newend = new Date(processed);
    shiftResources(newa.resources, oldend, newend);
    map(newa.spaces, (space) => {
      shiftResources(space.resources, oldend, newend);
    });
  }
};

// Aggregate usage and return new aggregated usage
const aggregate = function *(aggrs, u) {
  const a = aggrs[0];
  const c = aggrs[1];
  debug(
    'Aggregating usage %o from %d and new usage %o from %d',
    a, a ? a.end : 0, u, u.end);

  // Compute the aggregated usage time and new usage time
  const newend = u.processed;
  const docend = u.end;

  // Deep clone and revive the org aggregated usage object behavior
  const newa = a ?
    extend(reviveOrg(JSON.parse(JSON.stringify(a))), {
      account_id: u.account_id,
      end: u.end
    }) :
    extend(newOrg(u.organization_id), {
      start: u.start,
      end: u.end,
      account_id: u.account_id
    });

  const newc = c ? reviveCon(JSON.parse(JSON.stringify(c))) :
    newConsumer(u.consumer_id || 'UNKNOWN');

  const iddoc = extend({}, u, {
    accumulated_usage: map(u.accumulated_usage, (au) => {
      return extend({}, {
        metric: au.metric,
        windows: map(au.windows, (w) => {
          return map(w, (tw) => {
            return extend({}, tw);
          });
        })
      });
    }) }, {
      processed: u.processed,
      organization_doc_id: dbclient.kturi(okeys(u)[0], dbclient.t(u.id)),
      consumer_doc_id: dbclient.kturi(okeys(u)[1], dbclient.t(u.id))
    });

  shift(newa, a, u.processed);
  shift(newc, c, u.processed);

  // Get metering plan
  const mplan = yield mconfig(
      u.metering_plan_id, systemToken && systemToken());

  // Retrieve the rating plan
  const rplan = yield rconfig(
    u.rating_plan_id, systemToken && systemToken());

  // Go through the incoming accumulated usage metrics
  map(u.accumulated_usage, (ua) => {
    // Find the aggregate function for the given metric
    const afn = aggrfn(mplan.metrics, ua.metric);

    // Find the rate function for the given metric
    const rfn = ratefn(rplan.metrics, ua.metric);

    // Find the price for the metric
    const rp = price(u.prices.metrics, ua.metric);

    const aggr = (am, addCost) => {
      // We're mutating the input windows property here
      // but it's really the simplest way to apply the aggregation formula
      am.windows = map(am.windows, (w, i) => {
        // If the number of slack windows in the aggregated usage is less than
        // the number in the incoming accumulated usage, push until they equal
        if(w.length < ua.windows[i].length)
          map(Array(ua.windows[i].length - w.length), () =>
            w.push(null));

        const twi = timewindow.timeWindowIndex(w, new Date(newend),
          new Date(docend), dimensions[i]);

        /* eslint complexity: [1, 6] */
        const quantities = map(w, (q, j) => {
          // Instead of returning undefined or null,
          // returning previously aggregated quantity
          // TODO: Calculation has to use slack window to determine
          // what to do here
          if(!ua.windows[i][j] || twi !== j)
            return q;

          return {
            quantity: afn(q && q.quantity || 0,
              ua.windows[i][j].quantity.previous || 0,
              ua.windows[i][j].quantity.current)
          };
        });

        return addCost ? map(quantities, (q) => q ?
          extend(q, { cost: q.quantity ?
            rfn(rp, q.quantity) : 0 }) : null) : quantities;
      });

    };

    // Apply the aggregate function to the aggregated usage tree
    const pid = [u.plan_id, u.metering_plan_id, u.rating_plan_id,
      u.pricing_plan_id].join('/');
    aggr(
      newa.resource(u.resource_id).metric(ua.metric), false);
    aggr(
      newa.resource(u.resource_id).plan(pid)
      .metric(ua.metric), true);
    aggr(
      newa.space(u.space_id).resource(u.resource_id)
      .metric(ua.metric), false);
    aggr(
      newa.space(u.space_id).resource(u.resource_id).plan(pid)
      .metric(ua.metric), true);
    newa.resource_instance(okeys(u)[2], otimes(u)[2], u.processed);

    // Apply the aggregate function to the consumer usage tree
    newa.space(u.space_id).consumer(u.consumer_id || 'UNKNOWN',
      u.space_id, u.processed, dbclient.kturi(okeys(u)[1], dbclient.t(u.id)));
    aggr(newc.resource(u.resource_id).metric(ua.metric), false);
    aggr(
      newc.resource(u.resource_id).plan(pid).metric(ua.metric), true);
  });

  // Remove aggregated usage object behavior and return
  const jsa = JSON.parse(JSON.stringify([newa, newc, iddoc]));
  debug('New aggregated usage %o', jsa);
  return jsa;
};

// Aggregate the given accumulated usage
// Process a group of usage docs and compute the corresponding
// aggregated usage
const aggregateUsage = function *(aggrs, udocs) {
  const ologs = yield treduce(udocs, function *(log, udoc, i, l) {
    const res = yield aggregate(last(log), udoc);
    return log.concat([res]);

  }, [
    aggrs
  ]);
  return rest(ologs);
};

// Create an aggregator service app
const aggregator = () => {
  // Configure Node cluster to use a single process as we want to serialize
  // accumulation requests per db partition and app instance
  cluster.singleton();

  // Create the Webapp
  const app = webapp();

  // Secure metering and batch routes using an OAuth bearer access token
  if (secured())
    app.use(/^\/v1\/metering|^\/batch$/,
      oauth.validator(process.env.JWTKEY, process.env.JWTALGO));

  const reducer = dataflow.reducer(aggregateUsage, {
    input: {
      type: 'accumulated_usage',
      post: '/v1/metering/accumulated/usage',
      get: '/v1/metering/accumulated/usage/t/:tseq/k/:korganization_id',
      dbname: 'abacus-aggregator-accumulated-usage',
      wscope: iwscope,
      rscope: rscope,
      key: ikey,
      time: itime,
      groups: igroups
    },
    output: {
      type: 'aggregated_usage',
      get: '/v1/metering/aggregated/usage/k/:korganization_id/t/:tseq',
      dbname: 'abacus-aggregator-aggregated-usage',
      rscope: rscope,
      keys: okeys,
      times: otimes
    },
    sink: {
      host: process.env.SINK ? uris.sink : undefined,
      apps: process.env.AGGREGATOR_SINK_APPS,
      post: '/v1/metering/aggregated/usage',
      authentication: systemToken
    }
  });

  app.use(reducer);
  app.use(router.batch(app));

  app.reducer = reducer;
  return app;
};

// Command line interface, create the aggregator app and listen
const runCLI = () => {
  // Cache and schedule the system token renewal
  if (secured()) {
    systemToken = oauth.cache(uris.auth_server, process.env.CLIENT_ID,
      process.env.CLIENT_SECRET, 'abacus.usage.write abacus.usage.read');

    systemToken.start();
  }

  // Create the app, replay any failed events, and listen
  const app = aggregator();
  dataflow.replay(app.reducer, 0, () => {
    app.listen();
  });
};

// Export our public functions
module.exports = aggregator;
module.exports.newOrg = newOrg;
module.exports.reviveOrg = reviveOrg;
module.exports.runCLI = runCLI;


text:
"""Displays information about the current song in vlc, audacious, bmp, xmms2, spotify and others

Requires the following executable:
    * playerctl

Parameters:
    * playerctl.format:   Format string (defaults to '{{artist}} - {{title}}  {{duration(position)}}/{{duration(mpris:length)}}').
      The format string is passed to 'playerctl -f' as an argument. Read `the README <https://github.com/altdesktop/playerctl#printing-properties-and-metadata>`_ for more information.
    * playerctl.layout:   Comma-separated list to change order of widgets (defaults to song, previous, pause, next)
      Widget names are: playerctl.song, playerctl.prev, playerctl.pause, playerctl.next
    * playerctl.args:     The arguments added to playerctl.
      You can check 'playerctl --help' or `its README <https://github.com/altdesktop/playerctl#using-the-cli>`_. For example, it could be '-p vlc,%any'.
    * playerctl.hide:   Hide the widgets when no players are found. Defaults to "false".

Parameters are inspired by the `spotify` module, many thanks to its developers!

contributed by `smitajit <https://github.com/smitajit>`_ - many thanks!
"""

import core.module
import core.widget
import core.input
import util.cli
import util.format

import logging

class Module(core.module.Module):
    def __init__(self, config, theme):
        super(Module, self).__init__(config, theme, [])

        self.background = True

        self.__hide = util.format.asbool(self.parameter("hide", "false"));

        self.__layout = util.format.aslist(
            self.parameter(
                "layout", "playerctl.prev, playerctl.song, playerctl.pause, playerctl.next"
            )
        )

        self.__cmd = "playerctl " + self.parameter("args", "") + " "
        self.__format = self.parameter("format", "{{artist}} - {{title}}  {{duration(position)}}/{{duration(mpris:length)}}")

        widget_map = {}
        for widget_name in self.__layout:
            widget = self.add_widget(name=widget_name)
            if widget_name == "playerctl.prev":
                widget_map[widget] = {
                    "button": core.input.LEFT_MOUSE,
                    "cmd": self.__cmd + "previous",
                }
            elif widget_name == "playerctl.pause":
                widget_map[widget] = {
                    "button": core.input.LEFT_MOUSE,
                    "cmd": self.__cmd + "play-pause",
                }
            elif widget_name == "playerctl.next":
                widget_map[widget] = {
                    "button": core.input.LEFT_MOUSE,
                    "cmd": self.__cmd + "next",
                }
            elif widget_name == "playerctl.song":
                widget_map[widget] = [
                    {
                        "button": core.input.LEFT_MOUSE,
                        "cmd": self.__cmd + "play-pause",
                    }, {
                        "button": core.input.WHEEL_UP,
                        "cmd": self.__cmd + "next",
                    }, {
                        "button": core.input.WHEEL_DOWN,
                        "cmd": self.__cmd + "previous",
                    }
                ]
            else:
                raise KeyError(
                    "The playerctl module does not have a {widget_name!r} widget".format(
                        widget_name=widget_name
                    )
                )

        for widget, callback_options in widget_map.items():
            if isinstance(callback_options, dict):
                core.input.register(widget, **callback_options)

    def hidden(self):
        return self.__hide and self.status() == None

    def status(self):
        try:
            playback_status = str(util.cli.execute(self.__cmd + "status 2>&1 || true", shell = True)).strip()
            if playback_status == "No players found":
                return None
            return playback_status
        except Exception as e:
            logging.exception(e)
            return None

    def update(self):
        playback_status = self.status()
        for widget in self.widgets():
            if playback_status:
                if widget.name == "playerctl.pause":
                    if playback_status == "Playing":
                        widget.set("state", "playing")
                    elif playback_status == "Paused":
                        widget.set("state", "paused")
                    elif playback_status == "Stopped":
                        widget.set("state", "stopped")
                    else:
                        widget.set("state", "")
                elif widget.name == "playerctl.next":
                    widget.set("state", "next")
                elif widget.name == "playerctl.prev":
                    widget.set("state", "prev")
                elif widget.name == "playerctl.song":
                    widget.full_text(self.__get_song())
            else:
                widget.set("state", "")
                widget.full_text(" ")

    def __get_song(self):
        try:
            return str(util.cli.execute(self.__cmd + "metadata -f '" + self.__format + "'")).strip()
        except Exception as e:
            logging.exception(e)
            return " "


text:
/**
  * Scanner.cpp
  * Scanner class, similar to the Java scanner class
  *
  * MIT license, Felix Niederwanger
  * http://opensource.org/licenses/MIT
  */

#include <string>
#include <sstream>
#include <ctype.h>

#include "scanner.hpp"

#define NEXT_NONE 0
#define NEXT_TOKEN 1
#define NEXT_LINE 2

using namespace std;
using namespace flex;

Scanner::Scanner() {
	this->source = NULL;
	this->s_next = "";
	this->_deleteOnClosing = false;
    this->_nextStatus = NEXT_NONE;
    this->lastSeparator = '\0';
}

Scanner::Scanner(std::istream &input) {
	this->s_next = "";
	this->_deleteOnClosing = false;
    this->_nextStatus = NEXT_NONE;
    this->lastSeparator = '\0';

    this->source = &input;
}

Scanner::Scanner(std::string &input) {
	this->s_next = "";
	this->_deleteOnClosing = false;
    this->_nextStatus = NEXT_NONE;
    this->lastSeparator = '\0';

	this->source = &streamSource;
	this->streamSource << input;
}

Scanner::Scanner(const std::string &input) {
	this->s_next = "";
	this->_deleteOnClosing = false;
    this->_nextStatus = NEXT_NONE;
    this->lastSeparator = '\0';

	this->streamSource << input;
	this->source = &streamSource;
}

Scanner::Scanner(std::istream *input) {
	this->s_next = "";
	this->_deleteOnClosing = false;
    this->_nextStatus = NEXT_NONE;
    this->lastSeparator = '\0';

	this->source = input;
}

Scanner::~Scanner() {
    this->close();
}

String Scanner::next() {
	// Must scan manually for next?
	if(this->_nextStatus == NEXT_NONE) {
		this->hasNext();
	}
	return s_next;
}

String Scanner::nextLine() {
	// Must scan manually for next?
	if(this->_nextStatus == NEXT_NONE) {
		if(!this->hasNextLine()) return "";
	} else if(this->_nextStatus == NEXT_TOKEN) {
		// Add token and read until the end of the line
		stringstream buffer;
		buffer << s_next;
		char separator = this->lastSeparator;
		this->hasNextLine();
		buffer << (char)separator;
		buffer << this->s_next;
		String result(buffer.str());
		return result;
	}
	return s_next;
}

bool Scanner::hasNext() {
    if(this->eof()) return false;

    std::stringstream buffer;
    char c;

    while(!source->eof()) {
        source->get(c);
        if(isspace(c) || this->source->tellg() == -1) {
        	this->lastSeparator = c;
        	break;
        }
        else buffer << (char)c;
    }

    s_next = String(buffer.str());
    s_next = s_next.trim();
    this->_nextStatus = NEXT_TOKEN;
    return true;
}

bool Scanner::hasNextLine() {
    if(this->eof()) return false;

    std::stringstream buffer;
    char c;

    while(!source->eof()) {
        source->get(c);
        if(c == '\n') {
        	this->lastSeparator = c;
        	break;
        }
        else buffer << (char)c;
    }

    s_next = buffer.str();
    this->_nextStatus = NEXT_LINE;
    return true;
}

bool Scanner::eof(void) {
    if(this->source == NULL) return true;
    if(this->source->eof()) return true;
    return false;
}
void Scanner::close(void) {
    if(this->source == NULL) return;
    if(this->_deleteOnClosing) {
    	if(this->source != NULL) delete this->source;
        this->source = NULL;
    }
}

void Scanner::setDeleteOnClose(bool value) {
    this->_deleteOnClosing = value;
}

String Scanner::readAll(void) {
    std::stringstream buffer;

    char c;
    while(!source->eof()) {
        source->get(c);
        buffer << (char)c;
    }

    String result(buffer.str());
    return result;
}

std::vector<String> Scanner::readLines(bool cropEmtpy) {
	vector<String> result;
	while(this->hasNextLine()) {
		String line = this->nextLine();
		if(cropEmtpy && line.isEmpty()) continue;
		else
			result.push_back(line);
	}
	return result;
}

std::vector<String> Scanner::readTokens(bool cropEmtpy) {
	vector<String> result;
	while(this->hasNext()) {
		String token = this->next();
		if(cropEmtpy && token.isEmpty()) continue;
		else
			result.push_back(token);
	}
	return result;
}


text:
<?php
namespace Heyday\Component\Beam\Config;

/**
 * Generated by PHPUnit_SkeletonGenerator 1.2.0 on 2013-05-15 at 11:01:03.
 */
class DeploymentResultConfigurationTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var DeploymentResultConfiguration
     */
    protected $object;

    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp()
    {
        $this->object = new DeploymentResultConfiguration;
    }

    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */
    protected function tearDown()
    {
    }

    /**
     * @covers Heyday\Component\Beam\Config\DeploymentResultConfiguration::getConfigTreeBuilder
     * @todo   Implement testGetConfigTreeBuilder().
     */
    public function testGetConfigTreeBuilder()
    {
        // Remove the following lines when you implement this test.
        $this->markTestIncomplete(
          'This test has not been implemented yet.'
        );
    }
}


text:
import mimeparse

from django.http.response import HttpResponse, HttpResponseRedirect
from django.template.loader import render_to_string
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _

import import_string

from pyston.utils import set_rest_context_to_request
from pyston.converters import (
    get_converter, get_supported_mime_types, get_converter_name_from_request, get_default_converters
)
from pyston.resource import BaseResource
from pyston.conf import settings as pyston_settings

from is_core.config import settings

__all__ = (
    'ResponseException',
    'HttpRedirectResponseException',
    'HttpBadRequestResponseException',
    'HttpUnauthorizedResponseException',
    'HttpForbiddenResponseException',
    'HttpUnsupportedMediaTypeResponseException',
    'HttpMethodNotAllowedResponseException',
    'HttpDuplicateResponseException',
    'HttpServiceUnavailableException',
)

def ui_response_exception_factory(request, response_code, title, message, response_class=HttpResponse):
    if isinstance(message, (list, tuple)):
        message = ', '.join(message)

    return response_class(
        render_to_string(
            ('is_core/{}.html'.format(response_code), 'is_core/error.html'),
            {'response_code': response_code, 'title': title, 'message': message},
            request=request
        ),
        status=response_code
    )

def rest_response_exception_factory(request, response_code, title, message, response_class=HttpResponse,
                                    rest_error_response_class=None):
    message = (
        ', '.join([force_text(val) for val in message])
        if isinstance(message, (list, tuple))
        else force_text(message)
    ) if message else force_text(title)
    set_rest_context_to_request(request, BaseResource.DEFAULT_REST_CONTEXT_MAPPING)
    converter_name = get_converter_name_from_request(request)
    converter = get_converter(converter_name)
    response = response_class(status=response_code, content_type=converter.content_type)

    rest_error_response_class = rest_error_response_class or import_string(pyston_settings.ERROR_RESPONSE_CLASS)

    converter.encode_to_stream(response, rest_error_response_class(msg=message, code=response_code).result)
    return response

def ui_rest_response_exception_factory(request, response_code, title, message, response_class=HttpResponse):
    rest_mime_types = list(get_supported_mime_types(get_default_converters()))
    ui_mime_types = ['text/html', 'application/xhtml+xml']

    try:
        best_match = mimeparse.best_match(rest_mime_types + ui_mime_types, request.META.get('HTTP_ACCEPT', 'text/html'))
    except ValueError:
        best_match = None

    if best_match in ui_mime_types:
        return ui_response_exception_factory(request, response_code, title, message, response_class)
    else:
        return rest_response_exception_factory(request, response_code, title, message, response_class)

def response_exception_factory(request, response_code, title, message, response_class=HttpResponse):
    return import_string(settings.RESPONSE_EXCEPTION_FACTORY)(request, response_code, title, message, response_class)

class ResponseException(Exception):

    def __init__(self, message=None):
        self.message = message

    def get_response(self, request):
        return response_exception_factory(request, self.status_code, self.title, self.message)

class HttpRedirectResponseException(ResponseException):

    def __init__(self, url):
        self.url = url

    def get_response(self, request):
        return HttpResponseRedirect(self.url)

class HttpBadRequestResponseException(ResponseException):

    title = _('Bad Request')
    status_code = 400

class HttpUnauthorizedResponseException(ResponseException):

    title = _('Unauthorized')
    status_code = 401

class HttpForbiddenResponseException(ResponseException):

    title = _('Forbidden')
    status_code = 403

class HttpUnsupportedMediaTypeResponseException(ResponseException):

    title = _('Unsupported Media Type')
    status_code = 415

class HttpMethodNotAllowedResponseException(ResponseException):

    title = _('Method Not Allowed')
    status_code = 405

class HttpDuplicateResponseException(ResponseException):

    title = _('Conflict/Duplicate')
    status_code = 409

class HttpServiceUnavailableException(ResponseException):

    title = _('Temporarily unavailable')
    status_code = 503


text:
function output_image = color_correct_image(input_image, light_color, light_color_G, light_color_B)
% COLOR_CORRECT_IMAGE: Support function for gamut_mapping.m
%
%   This function will color correct the input image, given the specified
%   color of the light source.
%

if ((nargin > 4) | (nargin < 2) | (nargin == 3))
    error('Input image AND color of the light source should be specified!');
    return;
end
if (nargin ==4)
    light_color(1) = light_color;
    light_color(2) = light_color_G;
    light_color(3) = light_color_B;
end

light_color = light_color ./ norm(light_color);

output_image(:,:,1) = input_image(:,:,1) ./ (light_color(1)*sqrt(3));
output_image(:,:,2) = input_image(:,:,2) ./ (light_color(2)*sqrt(3));
output_image(:,:,3) = input_image(:,:,3) ./ (light_color(3)*sqrt(3));


text:
from flask import render_template, request
from . import music
from . service import recommend

@music.route('/search', methods=['GET'])
def search():
    return render_template('cloudmusic/search.html')

@music.route('/result', methods=['POST'])
def result():
    data = request.values.get('username')
    user = recommend(data)

    return render_template('cloudmusic/result.html', user=user)


text:
package com.wci.umls.server.jpa.services.rest;

import com.wci.umls.server.ReleaseInfo;
import com.wci.umls.server.helpers.ReleaseInfoList;
import com.wci.umls.server.jpa.ReleaseInfoJpa;

/**
 * Represents a history services available via a REST service.
 */
public interface HistoryServiceRest {

  /**
   * Returns the release history.
   *
   * @param terminology the terminology
   * @param authToken the auth token
   * @return the release history
   * @throws Exception the exception
   */
  public ReleaseInfoList getReleaseHistory(String terminology, String authToken)
    throws Exception;

  /**
   * Returns the current release info.
   *
   * @param terminology the terminology
   * @param authToken the auth token
   * @return the current release info
   * @throws Exception the exception
   */
  public ReleaseInfo getCurrentReleaseInfo(String terminology, String authToken)
    throws Exception;

  /**
   * Returns the previous release info.
   *
   * @param terminology the terminology
   * @param authToken the auth token
   * @return the previous release info
   * @throws Exception the exception
   */
  public ReleaseInfo getPreviousReleaseInfo(String terminology, String authToken)
    throws Exception;

  /**
   * Gets the planned release info.
   *
   * @param terminology the terminology
   * @param authToken the auth token
   * @return the planned release info
   * @throws Exception the exception
   */
  public ReleaseInfo getPlannedReleaseInfo(String terminology, String authToken)
    throws Exception;

  /**
   * Returns the release info.
   *
   * @param terminology the terminology
   * @param name the name
   * @param authToken the auth token
   * @return the release info
   * @throws Exception the exception
   */
  public ReleaseInfo getReleaseInfo(String terminology, String name,
    String authToken) throws Exception;

  /**
   * Adds the release info.
   *
   * @param releaseInfo the release info
   * @param authToken the auth token
   * @return the release info
   * @throws Exception the exception
   */
  public ReleaseInfo addReleaseInfo(ReleaseInfoJpa releaseInfo, String authToken)
    throws Exception;

  /**
   * Updates release info.
   *
   * @param releaseInfo the release info
   * @param authToken the auth token
   * @throws Exception the exception
   */
  public void updateReleaseInfo(ReleaseInfoJpa releaseInfo, String authToken)
    throws Exception;

  /**
   * Removes the release info.
   *
   * @param id the id
   * @param authToken the auth token
   * @throws Exception the exception
   */
  public void removeReleaseInfo(Long id, String authToken) throws Exception;

  /**
   * Start editing cycle for a release.
   *
   * @param releaseVersion the release version
   * @param terminology the terminology
   * @param version the version
   * @param authToken the auth token
   * @throws Exception the exception
   */
  public void startEditingCycle(String releaseVersion, String terminology,
    String version, String authToken) throws Exception;

}


text:
    <stats number="{{users.length}}" comments="Esperando" colour="yellow" type="flag-checkered" goto="dashboard.usersInBank"></stats>
    <stats number="{{$parent.atendidos}}" comments="Atendidos" colour="green" type="support" goto="dashboard.usersInBank"></stats>

Clientes en Espera

                                Foto
                                Nombre
                                ¿Necesidades especiales?
                                ¿Premium?
                                Más

                                {{user.firstName}}
                                {{user.specialAssistance ? 'Si' : 'No'}}
                                {{user.premium ? 'Si' : 'No'}}

                                    <button type="button" class="btn btn-default btn-circle" ng-click="toUserRequirements(user)"></button>


text:
/*
 * Licensed 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.
 */
/*
 * This code was generated by https://github.com/google/apis-client-generator/
 * (build: 2017-11-07 19:12:12 UTC)
 * on 2017-11-12 at 01:28:45 UTC
 * Modify at your own risk.
 */

package com.appspot.mpitester_13.station.model;

/**
 * Model definition for ApiApiMessagesPlotMessage.
 *
 *
 This is the Java data model class that specifies how to parse/serialize into the JSON that is
 * transmitted over HTTP when working with the station. For a detailed explanation see:
 * https://developers.google.com/api-client-library/java/google-http-java-client/json
 *

 *
 * @author Google, Inc.
 */
@SuppressWarnings("javadoc")
public final class ApiApiMessagesPlotMessage extends com.google.api.client.json.GenericJson {

  /**
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key
  private java.lang.String plot;

  /**
   * The value may be {@code null}.
   */
  @com.google.api.client.util.Key("station_id")
  private java.lang.String stationId;

  /**
   * @see #decodePlot()
   * @return value or {@code null} for none
   */
  public java.lang.String getPlot() {
    return plot;
  }

  /**

   * @see #getPlot()
   * @return Base64 decoded value or {@code null} for none
   *
   * @since 1.14
   */
  public byte[] decodePlot() {
    return com.google.api.client.util.Base64.decodeBase64(plot);
  }

  /**
   * @see #encodePlot()
   * @param plot plot or {@code null} for none
   */
  public ApiApiMessagesPlotMessage setPlot(java.lang.String plot) {
    this.plot = plot;
    return this;
  }

  /**

   * @see #setPlot()
   *
   *

   * The value is encoded Base64 or {@code null} for none.
   *

   *
   * @since 1.14
   */
  public ApiApiMessagesPlotMessage encodePlot(byte[] plot) {
    this.plot = com.google.api.client.util.Base64.encodeBase64URLSafeString(plot);
    return this;
  }

  /**
   * @return value or {@code null} for none
   */
  public java.lang.String getStationId() {
    return stationId;
  }

  /**
   * @param stationId stationId or {@code null} for none
   */
  public ApiApiMessagesPlotMessage setStationId(java.lang.String stationId) {
    this.stationId = stationId;
    return this;
  }

  @Override
  public ApiApiMessagesPlotMessage set(String fieldName, Object value) {
    return (ApiApiMessagesPlotMessage) super.set(fieldName, value);
  }

  @Override
  public ApiApiMessagesPlotMessage clone() {
    return (ApiApiMessagesPlotMessage) super.clone();
  }

}


text:
namespace gmq {

class StompClient {
public:
    using StompTransactions = std::unordered_map<std::string, StompConnectionPtr>;
    using FrameHandler = std::function<void (StompClient*, StompFramePtr, StompConnectionPtr)>;

public:
    StompClient(const std::string& subid = "");
    ~StompClient();

    int connect(const std::string& url);
    int disconnect();

    int send(const std::string& dest, const std::string& body);
    int send(const std::string& dest, const std::string& body,
        const std::string& tx, const std::string& content_type = "");

    int subscribe(const std::string& dest, const AckMode ack = AckMode::AUTO);
    int unsubscribe();

    int begin(const std::string& tx);
    int commit(const std::string& tx);
    int abort(const std::string& tx);

    void on_tcp_connected(StompConnectionPtr conn);

    void dispatch(const StompFrames& frames, StompConnectionPtr conn);

    void set_listener(StompListenerPtr listener) { listener_ = listener; }

private:
    int ack(StompConnectionPtr conn, const std::string& id, const std::string& tx = "");
    int nack(StompConnectionPtr conn, const std::string& id, const std::string& tx = "");

    void on_frame_connected(StompFramePtr frame, StompConnectionPtr conn);
    void on_frame_message(StompFramePtr frame, StompConnectionPtr conn);
    void on_frame_receipt(StompFramePtr frame, StompConnectionPtr conn);
    void on_frame_error(StompFramePtr frame, StompConnectionPtr conn);

    int send_frame(StompFramePtr frame, StompConnectionPtr conn = nullptr);

private:
    static const FrameHandler frame_handlers_[4];

private:
    std::string login_;
    std::string passcode_;
    std::string heartbeat_;
    std::string subid_;

    std::vector<StompConnectionPtr> conns_;
    RrSelector selector_;
    StompTransactions transactions_;

    StompListenerPtr listener_ = { nullptr };

    StompState state_ = {StompState::CLOSED};
    std::string receipt_id_ = {""};
};

typedef std::shared_ptr<StompClient> StompClientPtr;

}

#endif


text:
package trendli.me.makhana.masterserver.db;

/**
 * AccountRepository is an interface which is implemented by a backing database.
 *
 * @author Elliott Butler
 *
 */
public interface AccountRepository
{

    /**
     * Returns the user account from this database by accountname reference.
     *
     * @param accountName
     *            the accountname of the account to return
     * @return the user account with the specified accountname
     */
    public Account getAccount( String accountName );

}


text:
SnooScreens
=============

SnooScreens allows you to change your wallpaper based on the front page of the subreddit or mulitreddit of your choice. You simply pick a subreddit or multireddit and an activation method using Activator and you're good to go! There are also options for allowing or blocking NSFW images, setting to the home screen, lock screen, or both, saving to the photo library, and using the top image post on a subreddit, or a random one from the front page (top 25).

There are 5 separate Activator listeners, so you can get wallpapers from different subreddits at different times or occasions. Each listener has its own independent settings, so one can set your lock screen to the top post of /r/spaceporn at 6:30 AM, save it to your library, and block NSFW images, while another could set your home screen to a random post from the front page of /r/wallpaper when you shake your phone, allowing NSFW images and not saving it to your photo library. And you can have any permutation of these settings with 5 different listeners.

While SnooScreens is a commercial tweak, it is still open source.

Special thanks to HASHBANG Productions for DailyPaper, Ben Rosen and CPDigitalDarkroom for Faces, CPDigitalDarkroom for help with the preference bundle, and uroboro for lots of stuff :)

###TODO:

* ~~Prevent duplicate photo saves (CFPreference Utils) - biggest hoop: what if they change the wallpaper on their own in between?~~
* Resize images
* ~~Prevent downloading the same image (CFPreference Utils)~~
* Skip wallpaper option (some sort of timer to keep looking if you're not happy. I want it to be unintrusive and let the user do nothing if they're happy with the wallpaper)
* Bring up wallpaper view (Look into [SBSUIWallpaperPreviewViewController](http://developer.limneos.net/index.php?ios=8.0&framework=SpringBoardUIServices.framework&header=SBSUIWallpaperPreviewViewController.h) and [PLWallpaperImageViewController](http://developer.limneos.net/index.php?ios=8.0&framework=PhotoLibrary.framework&header=PLWallpaperImageViewController.h)).
* Save into a specific album.
* ~~Individual save wallpaper button~~

![Settings pane](/screenshots/1.jpg?raw=true) ![Subreddit settings](/screenshots/2.jpg?raw=true) ![Activator](/screenshots/3.jpg?raw=true)

Licensed under MIT License

    The MIT License (MIT)

    Copyright (c) [year] [fullname]

    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.


text:
package transformations.structure;

import generators.data.AbstractAsynchronousWorker;

import org.openrdf.model.Literal;
import org.openrdf.model.Model;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.impl.LinkedHashModel;
import org.openrdf.model.impl.ValueFactoryImpl;

import transformations.InvalidTransformation;
import transformations.Transformation;

public class ExtractProperty  implements Transformation{
		private int N;
	    private static ValueFactory sesameValueFactory = ValueFactoryImpl.getInstance();

		public ExtractProperty(int N){
			this.N = N;
		}
		@SuppressWarnings("finally")
		public Model executeStatement(Statement arg) {
			Model model = new LinkedHashModel();

		    if(arg instanceof Statement){
				if(arg.getObject() instanceof Literal){
		    		String s = arg.getObject().stringValue();
			    	int base = s.length() / N;
				    int remainder = s.length() % N;

				    String[] parts = new String[N];
				    for (int i = 0; i < N; i++) {
				        int length = base + (i < remainder ? 1 : 0);
				        parts[i] = s.substring(0, length);
				        s = s.substring(length);

				        URI predicate = sesameValueFactory.createURI((arg.getPredicate().stringValue() + Integer.toString(i)));
						Value object = sesameValueFactory.createLiteral(parts[i]);
						model.add(arg.getSubject(), predicate ,object,arg.getContext());
						AbstractAsynchronousWorker.addToextendOntologyProps(predicate.toString());
				    }
		    	}
		    	//else{ model.add(st);}
		    }
			else{
				try {
					throw new InvalidTransformation();
				} catch (InvalidTransformation e) {
					e.printStackTrace();
				}finally{
					return model;
				}
			}
			return model;
		}

		@Override
		public String print() {
			// TODO Auto-generated method stub
			return null;
		}

		@Override
		public Object execute(Object arg) {
			// TODO Auto-generated method stub
			return null;
		}
	}