text:
package in.rahulja.groupingmessages;

import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.simmetrics.StringMetric;
import org.simmetrics.metrics.StringMetrics;

@SuppressWarnings("WeakerAccess") class TrainSms {

  private static final String CLEAN_SMS = DatabaseContract.Sms.KEY_CLEANED_SMS;
  private static final int LIMIT_SIM_SCORE = 80;
  private static String[] stopWordsofwordnet = {
      "without", "see", "unless", "due", "also", "must", "might", "like", "will", "may", "can",
      "much", "every", "the", "in", "other", "this", "the", "many", "any", "an", "or", "for", "in",
      "an", "an ", "is", "a", "about", "above", "after", "again", "against", "all", "am", "an",
      "and", "any", "are", "arent", "as", "at", "be", "because", "been", "before", "being", "below",
      "between", "both", "but", "by", "cant", "cannot", "could", "couldnt", "did", "didnt", "do",
      "does", "doesnt", "doing", "dont", "down", "during", "each", "few", "for", "from", "further",
      "had", "hadnt", "has", "hasnt", "have", "havent", "having", "he", "hed", "hell", "hes", "her",
      "here", "heres", "hers", "herself", "him", "himself", "his", "how", "hows", "i ", " i", "id",
      "ill", "im", "ive", "if", "in", "into", "is", "isnt", "it", "its", "its", "itself", "lets",
      "me", "more", "most", "mustnt", "my", "myself", "no", "nor", "not", "of", "off", "on", "once",
      "only", "ought", "our", "ours", "ourselves", "out", "over", "own", "same", "shant", "she",
      "shed", "shell", "shes", "should", "shouldnt", "so", "some", "such", "than", "that", "thats",
      "their", "theirs", "them", "themselves", "then", "there", "theres", "these", "they", "theyd",
      "theyll", "theyre", "theyve", "this", "those", "through", "to", "too", "under", "until", "up",
      "very", "was", "wasnt", "we", "wed", "well", "were", "weve", "were", "werent", "what",
      "whats", "when", "whens", "where", "wheres", "which", "while", "who", "whos", "whom", "why",
      "whys", "with", "wont", "would", "wouldnt", "you", "youd", "youll", "youre", "youve", "your",
      "yours", "yourself", "yourselves", "without", "see", "unless", "due", "also", "must", "might",
      "like", "will", "may", "can", "much", "every", "the", "in", "other", "this", "the", "many",
      "any", "an", "or", "for", "in", "an", "an ", "is", "a", "about", "above", "after", "again",
      "against", "all", "am", "an", "and", "any", "are", "arent", "as", "at", "be", "because",
      "been", "before", "being", "below", "between", "both", "but", "by", "cant", "cannot", "could",
      "couldnt", "did", "didnt", "do", "does", "doesnt", "doing", "dont", "down", "during", "each",
      "few", "for", "from", "further", "had", "hadnt", "has", "hasnt", "have", "havent", "having",
      "he", "hed", "hell", "hes", "her", "here", "heres", "hers", "herself", "him", "himself",
      "his", "how", "hows", "i ", " i", "id", "ill", "im", "ive", "if", "in", "into", "is", "isnt",
      "it", "its", "its", "itself", "lets", "me", "more", "most", "mustnt", "my", "myself", "no",
      "nor", "not", "of", "off", "on", "once", "only", "ought", "our", "ours", "ourselves", "out",
      "over", "own", "same", "shant", "she", "shed", "shell", "shes", "should", "shouldnt", "so",
      "some", "such", "than", "that", "thats", "their", "theirs", "them", "themselves", "then",
      "there", "theres", "these", "they", "theyd", "theyll", "theyre", "theyve", "this", "those",
      "through", "to", "too", "under", "until", "up", "very", "was", "wasnt", "we", "wed", "well",
      "were", "weve", "were", "werent", "what", "whats", "when", "whens", "where", "wheres",
      "which", "while", "who", "whos", "whom", "why", "whys", "with", "wont", "would", "wouldnt",
      "you", "youd", "youll", "youre", "youve", "your", "yours", "yourself", "yourselves"
  };
  private static final Set<String> stopWordsSet = new HashSet<>(Arrays.asList(stopWordsofwordnet));

  private TrainSms() {
    // empty constructor
  }

  public static List<Map<String, String>> getTrainedListOfSms(Context context,
      List<Map<String, String>> smsListToTrain, List<Map<String, String>> smsListToTrainAgainst) {

    List<Map<String, String>> trainedLatestSmsList = new ArrayList<>();

    List<Map<String, String>> cleanedSmsListToTrain = cleanListOfSms(smsListToTrain);
    List<Map<String, String>> cleanedSmsListToTrainAgainst = cleanListOfSms(smsListToTrainAgainst);

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    String simAlgo = prefs.getString("key_similarity_algorithm", "levenshtein");
    double limitSimScore = prefs.getInt("key_similarity_score", LIMIT_SIM_SCORE) / (double) 100;

    for (Map<String, String> toTrainSmsMap : cleanedSmsListToTrain) {

      double highestSimScore = 0.0;
      toTrainSmsMap.put(
          DatabaseContract.Sms.KEY_SIM_SCORE,
          String.valueOf(0.0)
      );
      toTrainSmsMap.put(
          DatabaseContract.Sms.KEY_CATEGORY_ID,
          String.valueOf(1)
      );
      toTrainSmsMap.put(
          DatabaseContract.Sms.KEY_VISIBILITY,
          String.valueOf(1)
      );
      toTrainSmsMap.put(
          DatabaseContract.Sms.KEY_SIMILAR_TO,
          String.valueOf(0)
      );
      toTrainSmsMap.put(
          DatabaseContract.Sms.KEY_SENDER_TYPE,
          String.valueOf(-1)
      );

      for (Map<String, String> toTrainAgainstSmsMap : cleanedSmsListToTrainAgainst) {

        double tempSimScore = getSmsSimilarityScore(
            simAlgo,
            toTrainSmsMap.get(CLEAN_SMS),
            toTrainAgainstSmsMap.get(CLEAN_SMS)
        );

        if (tempSimScore >= limitSimScore && tempSimScore >= highestSimScore) {
          Log.d("GM/SimNewSms", String.format(
              "%s %s %s %s",
              String.valueOf(tempSimScore),
              String.valueOf(limitSimScore),
              String.valueOf(highestSimScore),
              toTrainSmsMap.toString()
          ));
          toTrainSmsMap.put(
              DatabaseContract.Sms.KEY_SIM_SCORE,
              String.valueOf(tempSimScore)
          );
          toTrainSmsMap.put(
              DatabaseContract.Sms.KEY_CATEGORY_ID,
              toTrainAgainstSmsMap.get(DatabaseContract.Sms.KEY_CATEGORY_ID)
          );
          toTrainSmsMap.put(
              DatabaseContract.Sms.KEY_SIMILAR_TO,
              toTrainAgainstSmsMap.get(DatabaseContract.Sms._ID)
          );
          highestSimScore = tempSimScore;
        }
      }

      trainedLatestSmsList.add(toTrainSmsMap);
    }

    Log.i("GM/getTrainedListOfSms", "Trained Latest SMS count: " + trainedLatestSmsList.size());
    return trainedLatestSmsList;
  }

  private static List<Map<String, String>> cleanListOfSms(List<Map<String, String>> smsList) {

    List<Map<String, String>> cleanedSmsList = new ArrayList<>();

    for (Map<String, String> smsMap : smsList) {
      cleanedSmsList.add(cleanSmsMap(smsMap));
    }

    return cleanedSmsList;
  }

  private static Map<String, String> cleanSmsMap(Map<String, String> sms) {

    if (sms.get(CLEAN_SMS) == null ||
        (sms.get(CLEAN_SMS) != null && sms.get(CLEAN_SMS).isEmpty())
        ) {
      sms.put(
          CLEAN_SMS,
          cleanString(sms.get(DatabaseContract.Sms.KEY_ADDRESS)
              + " "
              + sms.get(DatabaseContract.Sms.KEY_BODY))
      );
    }

    return sms;
  }

  private static String cleanString(String s) {
    String[] words = s.replaceAll("[\\p{P}]", " ")
        .replaceAll("\\s+", " ")
        .replaceAll("\\d", "1")
        .toLowerCase()
        .split(" ");
    StringBuilder wordsList = new StringBuilder();

    for (String word : words) {
      if (!stopWordsSet.contains(word)) {
        wordsList.append(" ").append(word);
      }
    }

    return wordsList.toString();
  }

  public static List<Map<String, String>> retrainExistingSms(Context context,
      Map<String, String> trainedSms) {

    List<Map<String, String>> allSms = DatabaseBridge.getAllSms(context);
    List<Map<String, String>> reTrainedSmsList = new ArrayList<>();
    List<Map<String, String>> cleanedAllSms = cleanListOfSms(allSms);
    Map<String, String> cleanedTrainedSms = cleanSmsMap(trainedSms);

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    String simAlgo = prefs.getString("key_similarity_algorithm", "levenshtein");
    double limitSimScore = prefs.getInt("key_similarity_score", LIMIT_SIM_SCORE) / (double) 100;

    for (Map<String, String> toTrainSmsMap : cleanedAllSms) {

      double highestSimScore =
          Double.parseDouble(toTrainSmsMap.get(DatabaseContract.Sms.KEY_SIM_SCORE));

      double tempSimScore = getSmsSimilarityScore(
          simAlgo,
          toTrainSmsMap.get(CLEAN_SMS),
          cleanedTrainedSms.get(CLEAN_SMS)
      );

      if (tempSimScore >= limitSimScore && tempSimScore >= highestSimScore) {
        toTrainSmsMap.put(
            DatabaseContract.Sms.KEY_SIM_SCORE,
            String.valueOf(tempSimScore)
        );
        toTrainSmsMap.put(
            DatabaseContract.Sms.KEY_CATEGORY_ID,
            cleanedTrainedSms.get(DatabaseContract.Sms.KEY_CATEGORY_ID)
        );
        toTrainSmsMap.put(
            DatabaseContract.Sms.KEY_SIMILAR_TO,
            cleanedTrainedSms.get(DatabaseContract.Sms._ID)
        );
        reTrainedSmsList.add(toTrainSmsMap);
      }
    }

    return reTrainedSmsList;
  }

  private static double getSmsSimilarityScore(String algo, String sms1, String sms2) {
    Method method;
    try {
      method = StringMetrics.class.getMethod(algo);
      StringMetric m = (StringMetric) method.invoke(null);
      return m.compare(sms1, sms2);
    } catch (IllegalAccessException | InvocationTargetException | SecurityException | NoSuchMethodException e) {
      Log.e("GM/simError", e.toString());
      return 0.0;
    }
  }
}


text:
* {
  box-sizing: border-box;
  color: #fff;
}
@font-face {
  font-family: Verdana;
  src: url('../../../../fonts/Verdana.ttf');
}
.vertical-align-middle {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
      -ms-flex-direction: column;
          flex-direction: column;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
      -ms-flex-pack: center;
          justify-content: center;
}
.scrollable-container {
  overflow-x: scroll;
  width: 1060;
  height: 530px;
  overflow-y: hidden;
}
.template-container {
  margin: 20px;
  width: 10000px;
}
/*Template styles */
/*Template hover styles*/
/*Template header*/
/*Template content*/
/*Template list*/
/*Template list item*/
/*Template footer*/
.template {
  width: 250px;
  height: 510px;
  border: 1px solid #b2b2b2 !important;
  box-shadow: 0;
  font-family: Verdana;
  text-align: center;
  float: left;
  -webkit-transition: box-shadow 0.25s;
          transition: box-shadow 0.25s;
  margin: 0 10px;
}
.template:last-child {
  margin-right: 0;
}
.template:first-child {
  margin-left: 0;
}
.template:hover {
  box-shadow: 0 0 15px 0 #8e8e8e !important;
}
.template:hover .template-header {
  background-color: #fd6e0e !important;
}
.template:hover .template-list .template-list-item-even {
  color: #fd6e0e !important;
}
.template .template-header {
  background-color: #fdd016 !important;
  height: 150px;
  max-height: 150px;
  font-size: 3em;
  font-weight: bold;
}
.template .template-content {
  height: 250px;
  max-height: 250px;
}
.template .template-list {
  max-height: 300px;
  height: 300px;
  padding: 0;
  margin: 0;
}
.template .template-list li {
  list-style: none;
  width: 100%;
  height: 35px;
  max-height: 35px;
  color: #23404c !important;
  font-size: 16px;
}
.template .template-list .template-list-item-even {
  background-color: #ffffff !important;
}
.template .template-list .template-list-item-odd {
  background-color: #ececec !important;
}
.template .template-footer {
  background-color: #ffffff !important;
  height: 100px;
  max-height: 100px;
  padding-bottom: 10px;
}
.template .template-footer span {
  color: #23404c !important;
}

redpajama_set_name: RedPajamaGithub


text:
class Supersync < Cask
  version :latest
  sha256 :no_check

  url 'https://supersync.com/downloads/SuperSync.app.zip'
  homepage 'http://supersync.com/'
  license :unknown

  app 'SuperSync.app'
end


text:
using namespace Halley;

void EntityIdHolder::serialize(Serializer& s) const
{
	s << value;
}

void EntityIdHolder::deserialize(Deserializer& s)
{
	s >> value;
}

ConfigNode::ConfigNode()
{
}

ConfigNode::ConfigNode(const ConfigNode& other)
{
	operator=(other);
}

ConfigNode::ConfigNode(ConfigNode&& other) noexcept
{
	*this = std::move(other);
}

ConfigNode::ConfigNode(MapType entryMap)
{
	operator=(std::move(entryMap));
}

ConfigNode::ConfigNode(SequenceType entryList)
{
	operator=(std::move(entryList));
}

ConfigNode::ConfigNode(String value)
{
	operator=(std::move(value));
}

ConfigNode::ConfigNode(const std::string_view& value)
{
	operator=(value);
}

ConfigNode::ConfigNode(bool value)
{
	operator=(value);
}

ConfigNode::ConfigNode(int value)
{
	operator=(value);
}

ConfigNode::ConfigNode(uint32_t value)
{
	operator=(value);
}

ConfigNode::ConfigNode(int64_t value)
{
	operator=(value);
}

ConfigNode::ConfigNode(EntityIdHolder value)
{
	operator=(value);
}

ConfigNode::ConfigNode(float value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Vector2i value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Vector2f value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Vector3i value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Vector3f value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Vector4i value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Vector4f value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Rect4i value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Rect4f value)
{
	operator=(value);
}

ConfigNode::ConfigNode(Bytes value)
{
	operator=(std::move(value));
}

ConfigNode::ConfigNode(NoopType value)
{
	operator=(value);
}

ConfigNode::ConfigNode(DelType value)
{
	operator=(value);
}

ConfigNode::ConfigNode(IdxType value)
{
	operator=(value);
}

void ConfigNode::removeKey(const String& key)
{
	asMap().erase(key);
}

ConfigNode::~ConfigNode()
{
	reset();
}

ConfigNode& ConfigNode::operator=(const ConfigNode& other)
{
	switch (other.type) {
		case ConfigNodeType::String:
			*this = other.asString();
			break;
		case ConfigNodeType::Sequence:
		case ConfigNodeType::DeltaSequence:
			*this = other.asSequence();
			break;
		case ConfigNodeType::Map:
		case ConfigNodeType::DeltaMap:
			*this = other.asMap();
			break;
		case ConfigNodeType::Int:
			*this = other.asInt();
			break;
		case ConfigNodeType::Int64:
			*this = other.asInt64();
			break;
		case ConfigNodeType::EntityId:
			*this = other.asEntityId();
			break;
		case ConfigNodeType::Float:
			*this = other.asFloat();
			break;
		case ConfigNodeType::Int2:
		case ConfigNodeType::Idx:
			*this = other.asVector2i();
			break;
		case ConfigNodeType::Float2:
			*this = other.asVector2f();
			break;
		case ConfigNodeType::Bytes:
			*this = other.asBytes();
			break;
		case ConfigNodeType::Undefined:
		case ConfigNodeType::Noop:
		case ConfigNodeType::Del:
			break;
		default:
			throw Exception("Unknown configuration node type.", HalleyExceptions::Resources);
	}

	type = other.type;
	auxData = other.auxData;

	return *this;
}

ConfigNode& ConfigNode::operator=(ConfigNode&& other) noexcept
{
	reset();

	type = other.type;
	rawPtrData = other.rawPtrData;
	intData = other.intData;
	floatData = other.floatData;
	vec2iData = other.vec2iData;
	vec2fData = other.vec2fData;
#if defined(STORE_CONFIG_NODE_PARENTING)
	parent = std::move(other.parent);
#endif
	auxData = other.auxData;

	other.type = ConfigNodeType::Undefined;
	other.rawPtrData = nullptr;

	return *this;
}

ConfigNode& ConfigNode::operator=(bool value)
{
	reset();
	type = ConfigNodeType::Int;
	intData = value ? 1 : 0;
	return *this;
}

ConfigNode& ConfigNode::operator=(int value)
{
	reset();
	type = ConfigNodeType::Int;
	intData = value;
	return *this;
}

ConfigNode& ConfigNode::operator=(uint32_t value)
{
	reset();
	type = ConfigNodeType::Int;
	intData = value;
	return *this;
}

ConfigNode& ConfigNode::operator=(int64_t value)
{
	reset();
	type = ConfigNodeType::Int64;
	int64Data = value;
	return *this;
}

ConfigNode& ConfigNode::operator=(EntityIdHolder value)
{
	reset();
	type = ConfigNodeType::EntityId;
	int64Data = value.value;
	return *this;
}

ConfigNode& ConfigNode::operator=(float value)
{
	reset();
	type = ConfigNodeType::Float;
	floatData = value;
	return *this;
}

ConfigNode& ConfigNode::operator=(Vector2i value)
{
	reset();
	type = ConfigNodeType::Int2;
	vec2iData = value;
	return *this;
}

ConfigNode& ConfigNode::operator=(Vector2f value)
{
	reset();
	type = ConfigNodeType::Float2;
	vec2fData = value;
	return *this;
}

ConfigNode& ConfigNode::operator=(Vector3i value)
{
	auto seq = SequenceType({ ConfigNode(value.x), ConfigNode(value.y), ConfigNode(value.z) });
	return *this = std::move(seq);
}

ConfigNode& ConfigNode::operator=(Vector3f value)
{
	auto seq = SequenceType({ ConfigNode(value.x), ConfigNode(value.y), ConfigNode(value.z) });
	return *this = std::move(seq);
}

ConfigNode& ConfigNode::operator=(Vector4i value)
{
	auto seq = SequenceType({ ConfigNode(value.x), ConfigNode(value.y), ConfigNode(value.z), ConfigNode(value.w) });
	return *this = std::move(seq);
}

ConfigNode& ConfigNode::operator=(Vector4f value)
{
	auto seq = SequenceType({ ConfigNode(value.x), ConfigNode(value.y), ConfigNode(value.z), ConfigNode(value.w) });
	return *this = std::move(seq);
}

ConfigNode& ConfigNode::operator=(Rect4i value)
{
	auto seq = SequenceType({ ConfigNode(value.getP1().x), ConfigNode(value.getP1().y), ConfigNode(value.getP2().x), ConfigNode(value.getP2().y) });
	return *this = std::move(seq);
}

ConfigNode& ConfigNode::operator=(Rect4f value)
{
	auto seq = SequenceType({ ConfigNode(value.getP1().x), ConfigNode(value.getP1().y), ConfigNode(value.getP2().x), ConfigNode(value.getP2().y) });
	return *this = std::move(seq);
}

ConfigNode& ConfigNode::operator=(Range<float> value)
{
	reset();
	type = ConfigNodeType::Float2;
	vec2fData = Vector2f(value.start, value.end);
	return *this;
}

ConfigNode& ConfigNode::operator=(Range<int> value)
{
	reset();
	type = ConfigNodeType::Int2;
	vec2iData = Vector2i(value.start, value.end);
	return *this;
}

ConfigNode& ConfigNode::operator=(const std::string_view& value)
{
	*this = String(value);
	return *this;
}

bool ConfigNode::operator==(const ConfigNode& other) const
{
	if (type != other.type) {
		return isEquivalent(other);
	}

	switch (type) {
		case ConfigNodeType::String:
			return asString() == other.asString();
		case ConfigNodeType::Sequence:
		case ConfigNodeType::DeltaSequence:
			return asSequence() == other.asSequence();
		case ConfigNodeType::Map:
		case ConfigNodeType::DeltaMap:
			return asMap() == other.asMap();
		case ConfigNodeType::Int:
			return asInt() == other.asInt();
		case ConfigNodeType::Int64:
			return asInt64() == other.asInt64();
		case ConfigNodeType::EntityId:
			return asEntityId().value == other.asEntityId().value;
		case ConfigNodeType::Float:
			return std::abs(asFloat() - other.asFloat()) < 0.00001f;
		case ConfigNodeType::Int2:
		case ConfigNodeType::Idx:
			return asVector2i() == other.asVector2i();
		case ConfigNodeType::Float2:
			return asVector2f() == other.asVector2f();
		case ConfigNodeType::Bytes:
			return asBytes() == other.asBytes();
		default:
			return true;
	}
}

bool ConfigNode::operator!=(const ConfigNode& other) const
{
	return !(*this == other);
}

ConfigNode& ConfigNode::operator=(Bytes value)
{
	reset();
	type = ConfigNodeType::Bytes;
	bytesData = new Bytes(std::move(value));
	return *this;
}

ConfigNode& ConfigNode::operator=(gsl::span<const gsl::byte> bytes)
{
	reset();
	type = ConfigNodeType::Bytes;
	auto b = new Bytes(bytes.size_bytes());
	memcpy(b->data(), bytes.data(), bytes.size_bytes());
	bytesData = b;
	return *this;
}

ConfigNode& ConfigNode::operator=(MapType entry)
{
	reset();
	type = ConfigNodeType::Map;
	mapData = new MapType(std::move(entry));
	return *this;
}

ConfigNode& ConfigNode::operator=(SequenceType entry)
{
	reset();
	type = ConfigNodeType::Sequence;
	sequenceData = new SequenceType(std::move(entry));
	return *this;
}

ConfigNode& ConfigNode::operator=(const char* value)
{
	reset();
	type = ConfigNodeType::String;
	strData = new String(value);
	return *this;
}

ConfigNode& ConfigNode::operator=(String entry)
{
	reset();
	type = ConfigNodeType::String;
	strData = new String(std::move(entry));
	return *this;
}

ConfigNode& ConfigNode::operator=(NoopType value)
{
	reset();
	type = ConfigNodeType::Noop;
	return *this;
}

ConfigNode& ConfigNode::operator=(DelType value)
{
	reset();
	type = ConfigNodeType::Del;
	return *this;
}

ConfigNode& ConfigNode::operator=(IdxType value)
{
	reset();
	type = ConfigNodeType::Idx;
	vec2iData = Vector2i(value.start, value.len);
	return *this;
}

ConfigNodeType ConfigNode::getType() const
{
	return type;
}

void ConfigNode::serialize(Serializer& s) const
{
	s << type;

	switch (type) {
		case ConfigNodeType::String:
			s << asString();
			break;
		case ConfigNodeType::Sequence:
			s << asSequence();
			break;
		case ConfigNodeType::Map:
			s << asMap();
			break;
		case ConfigNodeType::Int:
			s << asInt();
			break;
		case ConfigNodeType::Int64:
			s << asInt64();
			break;
		case ConfigNodeType::EntityId:
			s << asEntityId().value;
			break;
		case ConfigNodeType::Float:
			s << asFloat();
			break;
		case ConfigNodeType::Int2:
		case ConfigNodeType::Idx:
			s << asVector2i();
			break;
		case ConfigNodeType::Float2:
			s << asVector2f();
			break;
		case ConfigNodeType::Bytes:
			s << asBytes();
			break;
		case ConfigNodeType::DeltaMap:
			s << asMap();
			s << auxData;
			break;
		case ConfigNodeType::DeltaSequence:
			s << asSequence();
			s << auxData;
			break;
		case ConfigNodeType::Undefined:
		case ConfigNodeType::Del:
		case ConfigNodeType::Noop:
		{
			break;
		}
		default:
			throw Exception("Unknown configuration node type.", HalleyExceptions::Resources);
	}

	const auto* state = s.getState<ConfigFileSerializationState>();
	if (state && state->storeFilePosition) {
#if defined(STORE_CONFIG_NODE_PARENTING)
		if (parent) {
			s << parent->line;
			s << parent->column;
		} else {
			s << 0 << 0;
		}
#else
		s << 0 << 0;
#endif
	}
}

void ConfigNode::deserialize(Deserializer& s)
{
	ConfigNodeType incomingType;
	s >> incomingType;

	switch (incomingType) {
		case ConfigNodeType::String:
			deserializeContents<String>(s);
			break;
		case ConfigNodeType::Sequence:
			deserializeContents<SequenceType>(s);
			break;
		case ConfigNodeType::Map:
			deserializeContents<MapType>(s);
			break;
		case ConfigNodeType::Int:
			deserializeContents<int>(s);
			break;
		case ConfigNodeType::Int64:
			deserializeContents<int64_t>(s);
			break;
		case ConfigNodeType::EntityId:
			deserializeContents<EntityIdHolder>(s);
			break;
		case ConfigNodeType::Float:
			deserializeContents<float>(s);
			break;
		case ConfigNodeType::Int2:
		case ConfigNodeType::Idx:
			deserializeContents<Vector2i>(s);
			break;
		case ConfigNodeType::Float2:
			deserializeContents<Vector2f>(s);
			break;
		case ConfigNodeType::Bytes:
			deserializeContents<Bytes>(s);
			break;
		case ConfigNodeType::DeltaMap:
			deserializeContents<MapType>(s);
			s >> auxData;
			break;
		case ConfigNodeType::DeltaSequence:
			deserializeContents<SequenceType>(s);
			s >> auxData;
			break;
		case ConfigNodeType::Noop:
		case ConfigNodeType::Del:
		case ConfigNodeType::Undefined:
		{
			break;
		}
		default:
			throw Exception("Unknown configuration node type.", HalleyExceptions::Resources);
	}

	type = incomingType;

	const auto state = s.getState<ConfigFileSerializationState>();
	if (state && state->storeFilePosition) {
		[[maybe_unused]] int line;
		[[maybe_unused]] int column;
		s >> line >> column;

#if defined(STORE_CONFIG_NODE_PARENTING)
		if (parent) {
			parent->line = line;
			parent->column = column;
		}
#endif
	}
}

int ConfigNode::asInt() const
{
	if (type == ConfigNodeType::Int) {
		return intData;
	} else if (type == ConfigNodeType::Float) {
		return int(floatData);
	} else if (type == ConfigNodeType::String) {
		return asString().toInteger();
	} else if (type == ConfigNodeType::Int64) {
		return int(int64Data);
	} else if (type == ConfigNodeType::EntityId && int64Data == -1) {
		return -1;
	} else {
		throw Exception(getNodeDebugId() + " cannot be converted to int.", HalleyExceptions::Resources);
	}
}

int64_t ConfigNode::asInt64() const
{
	if (type == ConfigNodeType::Int64 || type == ConfigNodeType::EntityId) {
		return int64Data;
	} else if (type == ConfigNodeType::Int) {
		return intData;
	} else if (type == ConfigNodeType::Float) {
		return int(floatData);
	} else if (type == ConfigNodeType::String) {
		return asString().toInteger();
	} else {
		throw Exception(getNodeDebugId() + " cannot be converted to int.", HalleyExceptions::Resources);
	}
}

EntityIdHolder ConfigNode::asEntityId() const
{
	if (type == ConfigNodeType::EntityId || type == ConfigNodeType::Int64) {
		return EntityIdHolder{ int64Data };
	} else if (type == ConfigNodeType::Int && intData == -1) {
		return EntityIdHolder{};
	} else if (type == ConfigNodeType::Float && std::abs(floatData + 1.0f) < 0.0001f) {
		return EntityIdHolder{};
	} else {
		throw Exception(getNodeDebugId() + " cannot be converted to EntityId.", HalleyExceptions::Resources);
	}
}

float ConfigNode::asFloat() const
{
	if (type == ConfigNodeType::Int) {
		return float(intData);
	} else if (type == ConfigNodeType::Float) {
		return floatData;
	} else if (type == ConfigNodeType::Int64) {
		return float(int64Data);
	} else if (type == ConfigNodeType::String) {
		return asString().toFloat();
	} else if (type == ConfigNodeType::EntityId && int64Data == -1) {
		return -1.0f;
	} else {
		throw Exception(getNodeDebugId() + " cannot be converted to float.", HalleyExceptions::Resources);
	}
}

bool ConfigNode::asBool() const
{
	if (type == ConfigNodeType::Int) {
		return intData != 0;
	} else if (type == ConfigNodeType::Float) {
		return floatData != 0;
	} else if (type == ConfigNodeType::Int64) {
		return int64Data != 0;
	} else if (type == ConfigNodeType::String) {
		const auto& str = asString();
		if (str == "true") {
			return true;
		} else if (str == "false") {
			return false;
		}
		return !asString().isEmpty();
	} else if (type == ConfigNodeType::EntityId) {
		return int64Data != -1;
	}
	return type != ConfigNodeType::Undefined;
}

Vector2i ConfigNode::asVector2i() const
{
	if (type == ConfigNodeType::Int2 || type == ConfigNodeType::Idx) {
		return vec2iData;
	} else if (type == ConfigNodeType::Float2) {
		return Vector2i(vec2fData);
	} else if (type == ConfigNodeType::Int || type == ConfigNodeType::Float) {
		return Vector2i(asInt(), 0);
	} else if (type == ConfigNodeType::Sequence) {
		auto& seq = asSequence();
		return Vector2i(seq.at(0).asInt(), seq.at(1).asInt());
	} else {
		throw Exception(getNodeDebugId() + " is not a vector2 type", HalleyExceptions::Resources);
	}
}

Vector2f ConfigNode::asVector2f() const
{
	if (type == ConfigNodeType::Int2) {
		return Vector2f(vec2iData);
	} else if (type == ConfigNodeType::Float2) {
		return vec2fData;
	} else if (type == ConfigNodeType::Int || type == ConfigNodeType::Float) {
		return Vector2f(asFloat(), 0);
	} else if (type == ConfigNodeType::Sequence) {
		auto& seq = asSequence();
		return Vector2f(seq.at(0).asFloat(), seq.at(1).asFloat());
	} else {
		throw Exception(getNodeDebugId() + " is not a vector2 type", HalleyExceptions::Resources);
	}
}

Vector3i ConfigNode::asVector3i() const
{
	if (type == ConfigNodeType::Sequence) {
		auto& seq = asSequence();
		return Vector3i(seq.at(0).asInt(), seq.size() >= 2 ? seq.at(1).asInt() : 0, seq.size() >= 3 ? seq.at(2).asInt() : 0);
	}
	else {
		throw Exception(getNodeDebugId() + " is not a vector3 type", HalleyExceptions::Resources);
	}
}

Vector3f ConfigNode::asVector3f() const
{
	if (type == ConfigNodeType::Sequence) {
		auto& seq = asSequence();
		return Vector3f(seq.at(0).asFloat(), seq.size() >= 2 ? seq.at(1).asFloat() : 0.0f, seq.size() >= 3 ? seq.at(2).asFloat() : 0.0f);
	} else {
		throw Exception(getNodeDebugId() + " is not a vector3 type", HalleyExceptions::Resources);
	}
}

Vector4i ConfigNode::asVector4i() const
{
	if (type == ConfigNodeType::Sequence) {
		auto& seq = asSequence();
		return Vector4i(seq.at(0).asInt(), seq.at(1).asInt(), seq.at(2).asInt(), seq.at(3).asInt());
	} else {
		throw Exception(getNodeDebugId() + " is not a vector4 type", HalleyExceptions::Resources);
	}
}

Vector4f ConfigNode::asVector4f() const
{
	if (type == ConfigNodeType::Sequence) {
		auto& seq = asSequence();
		return Vector4f(seq.at(0).asFloat(), seq.at(1).asFloat(), seq.at(2).asFloat(), seq.at(3).asFloat());
	} else {
		throw Exception(getNodeDebugId() + " is not a vector4 type", HalleyExceptions::Resources);
	}
}

Rect4i ConfigNode::asRect4i() const
{
	if (type == ConfigNodeType::Sequence) {
		auto& seq = asSequence();
		return Rect4i(Vector2i(seq.at(0).asInt(), seq.at(1).asInt()), Vector2i(seq.at(2).asInt(), seq.at(3).asInt()));
	} else {
		throw Exception(getNodeDebugId() + " is not a rect4 type", HalleyExceptions::Resources);
	}
}

Rect4f ConfigNode::asRect4f() const
{
	if (type == ConfigNodeType::Sequence) {
		auto& seq = asSequence();
		return Rect4f(Vector2f(seq.at(0).asFloat(), seq.at(1).asFloat()), Vector2f(seq.at(2).asFloat(), seq.at(3).asFloat()));
	} else {
		throw Exception(getNodeDebugId() + " is not a rect4 type", HalleyExceptions::Resources);
	}
}

Range<float> ConfigNode::asFloatRange() const
{
	if (type == ConfigNodeType::Int2) {
		return Range<float>(static_cast<float>(vec2iData.x), static_cast<float>(vec2iData.y));
	} else if (type == ConfigNodeType::Float2) {
		return Range<float>(vec2fData.x, vec2fData.y);
	} else if (type == ConfigNodeType::Sequence) {
		const auto& seq = asSequence();
		return Range<float>(seq.at(0).asFloat(), seq.at(1).asFloat());
	} else if (type == ConfigNodeType::Int || type == ConfigNodeType::Float) {
		const auto v = asFloat();
		return Range<float>(v, v);
	} else {
		throw Exception(getNodeDebugId() + " is not a range type", HalleyExceptions::Resources);
	}
}

const Bytes& ConfigNode::asBytes() const
{
	if (type == ConfigNodeType::Bytes) {
		return *bytesData;
	} else {
		throw Exception(getNodeDebugId() + " is not a byte sequence type", HalleyExceptions::Resources);
	}
}

Vector2i ConfigNode::asVector2i(Vector2i defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asVector2i();
	}
}

Vector2f ConfigNode::asVector2f(Vector2f defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asVector2f();
	}
}

Vector3i ConfigNode::asVector3i(Vector3i defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asVector3i();
	}
}

Vector3f ConfigNode::asVector3f(Vector3f defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asVector3f();
	}
}

Vector4i ConfigNode::asVector4i(Vector4i defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asVector4i();
	}
}

Vector4f ConfigNode::asVector4f(Vector4f defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asVector4f();
	}
}

Rect4i ConfigNode::asRect4i(Rect4i defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asRect4i();
	}
}

Rect4f ConfigNode::asRect4f(Rect4f defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asRect4f();
	}
}

Range<float> ConfigNode::asFloatRange(Range<float> defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asFloatRange();
	}
}

String ConfigNode::asString() const
{
	if (type == ConfigNodeType::String) {
		return *strData;
	} else if (type == ConfigNodeType::Int) {
		return toString(asInt());
	} else if (type == ConfigNodeType::Int64) {
		return toString(asInt64());
	} else if (type == ConfigNodeType::EntityId) {
		return toString(asEntityId().value);
	} else if (type == ConfigNodeType::Float) {
		return toString(asFloat());
	} else if (type == ConfigNodeType::Sequence) {
		String result = "[";
		bool first = true;
		for (auto& e: asSequence()) {
			if (!first) {
				result += ", ";
			}
			first = false;
			result += e.asString();
		}
		result += "]";
		return result;
	} else if (type == ConfigNodeType::Float2) {
		auto v = asVector2f();
		return "(" + toString(v.x) + ", " + toString(v.y) + ")";
	} else if (type == ConfigNodeType::Int2) {
		auto v = asVector2i();
		return "(" + toString(v.x) + ", " + toString(v.y) + ")";
	} else if (type == ConfigNodeType::Map) {
		return "{...}";
	} else if (type == ConfigNodeType::Undefined) {
		return "null";
	} else {
		throw Exception("Can't convert " + getNodeDebugId() + " from " + toString(getType()) + " to String.", HalleyExceptions::Resources);
	}
}

int ConfigNode::asInt(int defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asInt();
	}
}

int64_t ConfigNode::asInt64(int64_t defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asInt64();
	}
}

EntityIdHolder ConfigNode::asEntityId(EntityIdHolder defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asEntityId();
	}
}

float ConfigNode::asFloat(float defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asFloat();
	}
}

bool ConfigNode::asBool(bool defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asBool();
	}
}

String ConfigNode::asString(const std::string_view& defaultValue) const
{
	if (type == ConfigNodeType::Undefined) {
		return defaultValue;
	} else {
		return asString();
	}
}

const ConfigNode::SequenceType& ConfigNode::asSequence() const
{
	if (type == ConfigNodeType::Sequence || type == ConfigNodeType::DeltaSequence) {
		return *sequenceData;
	} else {
		throw Exception(getNodeDebugId() + " is not a sequence type", HalleyExceptions::Resources);
	}
}

const ConfigNode::MapType& ConfigNode::asMap() const
{
	if (type == ConfigNodeType::Map || type == ConfigNodeType::DeltaMap) {
		return *mapData;
	} else {
		throw Exception(getNodeDebugId() + " is not a map type", HalleyExceptions::Resources);
	}
}

ConfigNode::SequenceType& ConfigNode::asSequence()
{
	if (type == ConfigNodeType::Sequence || type == ConfigNodeType::DeltaSequence) {
		return *sequenceData;
	} else {
		throw Exception(getNodeDebugId() + " is not a sequence type", HalleyExceptions::Resources);
	}
}

ConfigNode::MapType& ConfigNode::asMap()
{
	if (type == ConfigNodeType::Map || type == ConfigNodeType::DeltaMap) {
		return *mapData;
	} else {
		throw Exception(getNodeDebugId() + " is not a map type", HalleyExceptions::Resources);
	}
}

size_t ConfigNode::getSequenceSize(size_t defaultValue) const
{
	if (type == ConfigNodeType::Sequence || type == ConfigNodeType::DeltaSequence) {
		return asSequence().size();
	} else {
		return defaultValue;
	}
}

void ConfigNode::ensureType(ConfigNodeType t)
{
	if (type != t) {
		switch (t) {
		case ConfigNodeType::Int:
			*this = 0;
			break;
		case ConfigNodeType::Int2:
			*this = Vector2i();
			break;
		case ConfigNodeType::Int64:
			*this = int64_t(0);
			break;
		case ConfigNodeType::EntityId:
			*this = EntityIdHolder{};
			break;
		case ConfigNodeType::Float:
			*this = 0.0f;
			break;
		case ConfigNodeType::Float2:
			*this = Vector2f();
			break;
		case ConfigNodeType::Sequence:
			*this = SequenceType();
			break;
		case ConfigNodeType::Map:
			*this = MapType();
			break;
		case ConfigNodeType::Bytes:
			*this = Bytes();
			break;
		case ConfigNodeType::String:
			*this = String();
			break;
		case ConfigNodeType::Undefined:
			reset();
			type = ConfigNodeType::Undefined;
			break;
		}
	}
}

bool ConfigNode::hasKey(const String& key) const
{
	if (type == ConfigNodeType::Map || type == ConfigNodeType::DeltaMap) {
		auto& map = asMap();
		auto iter = map.find(key);
		return iter != map.end() && iter->second.getType() != ConfigNodeType::Undefined;
	} else {
		return false;
	}
}

ConfigNode& ConfigNode::operator[](std::string_view key)
{
	return asMap()[key];
}

ConfigNode& ConfigNode::operator[](size_t idx)
{
	return asSequence().at(idx);
}

const ConfigNode& ConfigNode::operator[](std::string_view key) const
{
	const auto& map = asMap();
	const auto iter = map.find(key);
	if (iter != map.end()) {
		return iter->second;
	} else {
#if defined(STORE_CONFIG_NODE_PARENTING)
		undefinedConfigNode.setParent(this, -1);
		undefinedConfigNode.parent->file = parent ? parent->file : nullptr;
#endif
		undefinedConfigNodeName = key;
		return undefinedConfigNode;
	}
}

const ConfigNode& ConfigNode::operator[](size_t idx) const
{
	return asSequence().at(idx);
}

ConfigNode& ConfigNode::at(std::string_view key)
{
	auto& map = asMap();
	const auto iter = map.find(key);
	if (iter != map.end()) {
		return iter->second;
	} else {
#if defined(STORE_CONFIG_NODE_PARENTING)
		undefinedConfigNode.setParent(this, -1);
		undefinedConfigNode.parent->file = parent ? parent->file : nullptr;
#endif
		undefinedConfigNodeName = key;
		return undefinedConfigNode;
	}
}

const ConfigNode& ConfigNode::at(std::string_view key) const
{
	const auto& map = asMap();
	const auto iter = map.find(key);
	if (iter != map.end()) {
		return iter->second;
	} else {
#if defined(STORE_CONFIG_NODE_PARENTING)
		undefinedConfigNode.setParent(this, -1);
		undefinedConfigNode.parent->file = parent ? parent->file : nullptr;
#endif
		undefinedConfigNodeName = key;
		return undefinedConfigNode;
	}
}

Vector<ConfigNode>::iterator ConfigNode::begin()
{
	return asSequence().begin();
}

Vector<ConfigNode>::iterator ConfigNode::end()
{
	return asSequence().end();
}

Vector<ConfigNode>::const_iterator ConfigNode::begin() const
{
	return asSequence().begin();
}

Vector<ConfigNode>::const_iterator ConfigNode::end() const
{
	return asSequence().end();
}

void ConfigNode::reset()
{
	if (type == ConfigNodeType::Map || type == ConfigNodeType::DeltaMap) {
		delete mapData;
	} else if (type == ConfigNodeType::Sequence || type == ConfigNodeType::DeltaSequence) {
		delete sequenceData;
	} else if (type == ConfigNodeType::Bytes) {
		delete bytesData;
	} else if (type == ConfigNodeType::String) {
		delete strData;
	}
	rawPtrData = nullptr;
	type = ConfigNodeType::Undefined;
}

void ConfigNode::setOriginalPosition(int l, int c)
{
#if defined(STORE_CONFIG_NODE_PARENTING)
	if (!parent) {
		parent = std::make_unique<ParentingInfo>();
	}
	parent->line = l;
	parent->column = c;
#endif
}

void ConfigNode::setParent(const ConfigNode* p, int idx)
{
#if defined(STORE_CONFIG_NODE_PARENTING)
	if (!parent) {
		parent = std::make_unique<ParentingInfo>();
	}
	parent->node = p;
	parent->idx = idx;
#endif
}

void ConfigNode::propagateParentingInformation(const ConfigFile* file)
{
#if defined(STORE_CONFIG_NODE_PARENTING)
	if (!parent) {
		parent = std::make_unique<ParentingInfo>();
	}
	parent->file = file;
	if (type == ConfigNodeType::Sequence) {
		int i = 0;
		for (auto& e: asSequence()) {
			e.setParent(this, i++);
			e.propagateParentingInformation(file);
		}
	} else if (type == ConfigNodeType::Map) {
		int i = 0;
		for (auto& e: asMap()) {
			e.second.setParent(this, i++);
			e.second.propagateParentingInformation(file);
		}
	}
#endif
}

String ConfigNode::getNodeDebugId() const
{
	String value;
	switch (type) {
		case ConfigNodeType::String:
			value = "\"" + asString() + "\"";
			break;
		case ConfigNodeType::Sequence:
			value = "Sequence[" + toString(asSequence().size()) + "]";
			break;
		case ConfigNodeType::Map:
			value = "Map";
			break;
		case ConfigNodeType::Int:
			value = toString(asInt());
			break;
		case ConfigNodeType::Float:
			value = toString(asFloat());
			break;
		case ConfigNodeType::Int2:
			{
				auto v = asVector2i();
				value = "Vector2i(" + toString(v.x) + ", " + toString(v.y) + ")";
			}
			break;
		case ConfigNodeType::Float2:
			{
				auto v = asVector2f();
				value = "Vector2f(" + toString(v.x) + ", " + toString(v.y) + ")";
			}
			break;
		case ConfigNodeType::Bytes:
			value = "Bytes (" + String::prettySize(asBytes().size()) + ")";
			break;
		case ConfigNodeType::Undefined:
			value = "null";
			break;
	}

#if defined(STORE_CONFIG_NODE_PARENTING)
	if (parent) {
		String assetId = "unknown";
		if (parent->file) {
			assetId = parent->file->getAssetId();
		}
		return "Node \"" + backTrackFullNodeName() + "\" (" + value + ") at \"" + assetId + "(" + toString(parent->line + 1) + ":" + toString(parent->column + 1) + ")\"";
	}
#endif

	return "Node (" + value + ")";
}

String ConfigNode::backTrackFullNodeName() const
{
#if defined(STORE_CONFIG_NODE_PARENTING)
	if (parent && parent->node) {
		if (parent->node->type == ConfigNodeType::Sequence) {
			return parent->node->backTrackFullNodeName() + "[" + toString(parent->idx) + "]";
		} else if (parent->node->type == ConfigNodeType::Map) {
			auto& parentMap = parent->node->asMap();
			int i = 0;
			String name = "?";
			if (parent->idx == -1) {
				name = ConfigNode::undefinedConfigNodeName;
			} else {
				for (auto& e: parentMap) {
					if (i++ == parent->idx) {
						name = e.first;
						break;
					}
				}
			}
			return parent->node->backTrackFullNodeName() + "." + name;
		} else {
			return "?";
		}
	} else {
		return "~";
	}
#else
	return "";
#endif
}

int ConfigNode::convertTo(Tag<int> tag) const
{
	return asInt();
}

int64_t ConfigNode::convertTo(Tag<int64_t> tag) const
{
	return asInt64();
}

EntityIdHolder ConfigNode::convertTo(Tag<EntityIdHolder> tag) const
{
	return asEntityId();
}

float ConfigNode::convertTo(Tag<float> tag) const
{
	return asFloat();
}

bool ConfigNode::convertTo(Tag<bool> tag) const
{
	return asBool();
}

uint8_t ConfigNode::convertTo(Tag<uint8_t> tag) const
{
	return asInt();
}

uint16_t ConfigNode::convertTo(Tag<uint16_t> tag) const
{
	return asInt();
}

uint32_t ConfigNode::convertTo(Tag<uint32_t> tag) const
{
	return asInt();
}

uint64_t ConfigNode::convertTo(Tag<uint64_t> tag) const
{
	return asInt64();
}

Vector2i ConfigNode::convertTo(Tag<Vector2i> tag) const
{
	return asVector2i();
}

Vector2f ConfigNode::convertTo(Tag<Vector2f> tag) const
{
	return asVector2f();
}

Vector3i ConfigNode::convertTo(Tag<Vector3i> tag) const
{
	return asVector3i();
}

Vector3f ConfigNode::convertTo(Tag<Vector3f> tag) const
{
	return asVector3f();
}

Vector4i ConfigNode::convertTo(Tag<Vector4i> tag) const
{
	return asVector4i();
}

Vector4f ConfigNode::convertTo(Tag<Vector4f> tag) const
{
	return asVector4f();
}

Range<float> ConfigNode::convertTo(Tag<Range<float>> tag) const
{
	return asFloatRange();
}

String ConfigNode::convertTo(Tag<String> tag) const
{
	return asString();
}

const Bytes& ConfigNode::convertTo(Tag<Bytes&> tag) const
{
	return asBytes();
}

bool ConfigNode::isNullOrEmpty() const
{
	switch (type) {
	case ConfigNodeType::Undefined:
		return true;
	case ConfigNodeType::Map:
	case ConfigNodeType::DeltaMap:
		return asMap().empty();
	case ConfigNodeType::Sequence:
	case ConfigNodeType::DeltaSequence:
		return asSequence().empty();
	default:
		return false;
	}
}

bool ConfigNode::BreadCrumb::hasKeyAt(const String& key, int depth) const
{
	if (depth == 0) {
		return this->key == key;
	} else if (prev) {
		return prev->hasKeyAt(key, depth - 1);
	} else {
		return false;
	}
}

bool ConfigNode::BreadCrumb::hasIndexAt(int idx, int depth) const
{
	if (depth == 0) {
		return this->idx == idx;
	} else if (prev) {
		return prev->hasIndexAt(idx, depth - 1);
	} else {
		return false;
	}
}

ConfigNode ConfigNode::createDelta(const ConfigNode& from, const ConfigNode& to, const IDeltaCodeHints* hints)
{
	return doCreateDelta(from, to, BreadCrumb(), hints);
}

ConfigNode ConfigNode::applyDelta(const ConfigNode& from, const ConfigNode& delta)
{
	auto result = ConfigNode(from);
	result.applyDelta(delta);
	return result;
}

ConfigNode ConfigNode::doCreateDelta(const ConfigNode& from, const ConfigNode& to, const BreadCrumb& breadCrumb, const IDeltaCodeHints* hints)
{
	// This allows things (e.g. ConfigNodeSerializer) to return Noop for fields that should skip the delta, for example when a field is not relevant to save data
	if (to.getType() == ConfigNodeType::Noop) {
		return ConfigNode(NoopType());
	}

	if (from.getType() == to.getType()) {
		if (hints && hints->shouldBypass(breadCrumb)) {
			return ConfigNode(NoopType());
		}

		if (from.getType() == ConfigNodeType::Map) {
			auto delta = createMapDelta(from, to, breadCrumb, hints);
			delta.auxData = breadCrumb.idx.value_or(0);
			return delta;
		}

		if (from.getType() == ConfigNodeType::Sequence) {
			auto delta = createSequenceDelta(from, to, breadCrumb, hints);
			delta.auxData = breadCrumb.idx.value_or(0);
			return delta;
		}
	}

	// Can compare equals even if the types are different (e.g. float 12.0 and int 12)
	if (from == to) {
		// No change
		return ConfigNode(NoopType());
	}

	// If one is undefined, consider no change if the other is a sequence/map that is empty
	if ((from.getType() == ConfigNodeType::Undefined && to.isNullOrEmpty()) || (to.getType() == ConfigNodeType::Undefined && from.isNullOrEmpty())) {
		if (hints && hints->areNullAndEmptyEquivalent(breadCrumb)) {
			return ConfigNode(NoopType());
		}
	}

	// No delta coding available, return the outcome
	return ConfigNode(to);
}

ConfigNode ConfigNode::createMapDelta(const ConfigNode& from, const ConfigNode& to, const BreadCrumb& breadCrumb, const IDeltaCodeHints* hints)
{
	const auto& fromMap = from.asMap();
	const auto& toMap = to.asMap();

	// Shortcut if from is empty
	if (fromMap.empty()) {
		if (toMap.empty()) {
			return ConfigNode(NoopType());
		}
		auto result = ConfigNode(toMap);
		result.type = ConfigNodeType::DeltaMap;
		return result;
	}

	auto result = ConfigNode(MapType());
	result.type = ConfigNodeType::DeltaMap;

	// Store the new keys if there's a change
	for (const auto& [k, v]: toMap) {
		if (v.getType() != ConfigNodeType::Noop) {
			const auto origIter = fromMap.find(k);

			if (origIter != fromMap.end()) {
				// Was present before, delta compress and store if it's different
				auto delta = doCreateDelta(origIter->second, v, BreadCrumb(breadCrumb, k), hints);
				if (delta.getType() != ConfigNodeType::Noop) {
					result[k] = std::move(delta);
				}
			} else {
				// Is new, store all of it
				result[k] = ConfigNode(v);
			}
		}
	}

	// Remove old keys if they're deleted
	if (!hints || hints->canDeleteAnyKey()) {
		for (const auto& [k, v]: fromMap) {
			const auto newIter = toMap.find(k);
			if (newIter == toMap.end()) {
				// Key deleted
				if (!hints || hints->canDeleteKey(k, breadCrumb)) {
					result[k] = ConfigNode(DelType());
				}
			}
		}
	}

	// If it doesn't change the original map, just return noop
	if (result.asMap().empty()) {
		return ConfigNode(NoopType());
	}

	// TODO: if it replaces ALL of the original map, just return the new map?

	return result;
}

ConfigNode ConfigNode::createSequenceDelta(const ConfigNode& from, const ConfigNode& to, const BreadCrumb& breadCrumb, const IDeltaCodeHints* hints)
{
	auto tryExtend = [] (Vector<ConfigNode>& seq, int idx) -> bool
	{
		if (seq.empty() || seq.back().getType() != ConfigNodeType::Idx) {
			return false;
		}
		const auto prev = seq.back().asVector2i();
		if (prev.x + prev.y == idx) {
			seq.back() = IdxType(prev.x, idx - prev.x + 1);
			return true;
		}
		return false;
	};

	auto result = ConfigNode(SequenceType());
	result.type = ConfigNodeType::DeltaSequence;

	const auto& fromSeq = from.asSequence();
	const auto& toSeq = to.asSequence();
	auto& resultSeq = result.asSequence();

	if (fromSeq == toSeq) {
		return ConfigNode(NoopType());
	}
	if (!hints) {
		return ConfigNode(to);
	}

	bool hasNewData = false;
	size_t refCount = 0;

	for (size_t curIdx = 0; curIdx != toSeq.size(); ++curIdx) {
		const auto& curVal = toSeq[curIdx];

		// Ask the hints for the best element to compare with
		std::optional<size_t> matchIdx;
		if (hints) {
			matchIdx = hints->getSequenceMatch(fromSeq, curVal, curIdx, breadCrumb);
		}

		if (matchIdx) {
			// Found a match, delta code to that
			auto delta = result.doCreateDelta(fromSeq.at(matchIdx.value()), curVal, BreadCrumb(breadCrumb, static_cast<int>(curIdx)), hints);
			if (delta.getType() == ConfigNodeType::Noop) {
				// Nothing to encode, store a reference
				const int startIdx = static_cast<int>(matchIdx.value());
				++refCount;

				// Check if the last value can simply be extended
				if (!tryExtend(resultSeq, startIdx)) {
					resultSeq.emplace_back(ConfigNode(IdxType(startIdx, 1)));
				}
			} else {
				// Store delta
				resultSeq.emplace_back(std::move(delta));
				hasNewData = true;
			}
		} else {
			// Just store original
			resultSeq.push_back(curVal);
			hasNewData = true;
		}
	}

	// Check if it's just a permutation of the old data
	if (!hasNewData && refCount == fromSeq.size()) {
		if (hints && !hints->doesSequenceOrderMatter(breadCrumb)) {
			Vector<char> matches(fromSeq.size(), 0);
			for (const auto& e: resultSeq) {
				const auto range = e.asVector2i();
				for (int i = range.x; i < range.x + range.y; ++i) {
					++matches[i];
				}
			}
			bool redundant = true;
			for (auto& e: matches) {
				if (e != 1) {
					redundant = false;
					break;
				}
			}
			if (redundant) {
				return ConfigNode(NoopType());
			}
		}
	}

	if (resultSeq.size() == 1 && resultSeq.back().getType() == ConfigNodeType::Idx) {
		const auto idxData = resultSeq.back().asVector2i();
		if (idxData.x == 0 && idxData.y == static_cast<int>(fromSeq.size())) {
			return ConfigNode(NoopType());
		}
	}

	return result;
}

void ConfigNode::applyDelta(const ConfigNode& delta)
{
	if (delta.getType() == ConfigNodeType::Noop) {
		// Nothing to do
		return;
	}

	if (getType() == ConfigNodeType::Map && delta.getType() == ConfigNodeType::DeltaMap) {
		applyMapDelta(delta);
	} else if (getType() == ConfigNodeType::Sequence && delta.getType() == ConfigNodeType::DeltaSequence) {
		applySequenceDelta(delta);
	} else if (delta.getType() == ConfigNodeType::Idx || delta.getType() == ConfigNodeType::Del) {
		throw Exception("Invalid ConfigNode delta type at this position", HalleyExceptions::Utils);
	} else {
		*this = ConfigNode(delta);
	}
}

void ConfigNode::decayDeltaArtifacts()
{
	switch (type) {
	case ConfigNodeType::Map:
	case ConfigNodeType::DeltaMap:
		for (auto& [k, v]: asMap()) {
			v.decayDeltaArtifacts();
		}
		type = ConfigNodeType::Map;
		break;
	case ConfigNodeType::Sequence:
	case ConfigNodeType::DeltaSequence:
		for (auto& v: asSequence()) {
			v.decayDeltaArtifacts();
		}
		type = ConfigNodeType::Sequence;
		break;
	case ConfigNodeType::Idx:
	case ConfigNodeType::Noop:
	case ConfigNodeType::Del:
		reset();
		break;
	}
}

ConfigNodeType ConfigNode::getPromotedType(gsl::span<const ConfigNodeType> types, bool promoteUndefined)
{
	ConfigNodeType result = ConfigNodeType::Undefined;

	if (!types.empty()) {
		result = types[0];
		for (size_t i = 1; i < types.size(); ++i) {
			const auto a = types[i - 1];
			const auto b = types[i];

			if (a != b) {
				if (isScalarType(a, promoteUndefined) && isScalarType(b, promoteUndefined)) {
					result = (a == ConfigNodeType::Float || b == ConfigNodeType::Float) ? ConfigNodeType::Float : ((a == ConfigNodeType::Int64 || b == ConfigNodeType::Int64) ? ConfigNodeType::Int64 : ConfigNodeType::Int);
				} else if (isVector2Type(a, promoteUndefined) && isVector2Type(b, promoteUndefined)) {
					result = (a == ConfigNodeType::Float2 || b == ConfigNodeType::Float2) ? ConfigNodeType::Float2 : ConfigNodeType::Int2;
				} else {
					return ConfigNodeType::Undefined;
				}
			}
		}
	}

	return result;
}

bool ConfigNode::isScalarType(ConfigNodeType type, bool acceptUndefined)
{
	return type == ConfigNodeType::Int || type == ConfigNodeType::Float || type == ConfigNodeType::Int64 || (acceptUndefined && type == ConfigNodeType::Undefined);
}

bool ConfigNode::isVector2Type(ConfigNodeType type, bool acceptUndefined)
{
	return type == ConfigNodeType::Int2 || type == ConfigNodeType::Float2 || (acceptUndefined && type == ConfigNodeType::Undefined);
}

void ConfigNode::applyMapDelta(const ConfigNode& delta)
{
	auto& myMap = asMap();
	const auto& deltaMap = delta.asMap();

	for (const auto& [k, v]: deltaMap) {
		if (v.getType() == ConfigNodeType::Del) {
			// Erase existing
			myMap.erase(k);
		} else {
			const auto iter = myMap.find(k);
			if (iter != myMap.end()) {
				// Update existing
				iter->second.applyDelta(v);
			} else if (v.getType() != ConfigNodeType::Noop) {
				// Insert new
				myMap[k] = ConfigNode(v);
			}
		}
	}
}

void ConfigNode::applySequenceDelta(const ConfigNode& delta)
{
	const auto& mySeq = asSequence();
	const auto& deltaSeq = delta.asSequence();
	SequenceType result;

	for (const auto& v: deltaSeq) {
		if (v.getType() == ConfigNodeType::Idx) {
			// Simple index copying
			const auto indices = v.asVector2i();
			for (int i = indices.x; i < indices.x + indices.y; ++i) {
				result.emplace_back(mySeq.at(i));
			}
		} else if (v.getType() == ConfigNodeType::DeltaMap || v.getType() == ConfigNodeType::DeltaSequence) {
			// Apply delta
			auto value = ConfigNode(mySeq.at(v.auxData));
			value.applyDelta(v);
			result.emplace_back(std::move(value));
		} else {
			// New value
			Ensures(v.getType() != ConfigNodeType::Noop);
			result.emplace_back(v);
		}
	}

	*this = std::move(result);
}

bool ConfigNode::isEquivalent(const ConfigNode& other) const
{
	if (type < other.type) {
		return isEquivalentStrictOrder(other);
	} else {
		return other.isEquivalentStrictOrder(*this);
	}
}

bool ConfigNode::isEquivalentStrictOrder(const ConfigNode& other) const
{
	Expects(type < other.type);

	if (type == ConfigNodeType::Int && other.type == ConfigNodeType::Float) {
		return std::abs(asFloat() - other.asFloat()) < 0.00001f;
	}
	if (type == ConfigNodeType::Sequence && other.type == ConfigNodeType::Int2 && asSequence().size() >= 2) {
		return asVector2i() == other.asVector2i();
	}
	if (type == ConfigNodeType::Sequence && other.type == ConfigNodeType::Float2 && asSequence().size() >= 2) {
		return asVector2f() == other.asVector2f();
	}

	return false;
}

size_t ConfigNode::getSizeBytes() const
{
	size_t result = sizeof(ConfigNode);

	switch (type) {
	case ConfigNodeType::Bytes:
		result += sizeof(Bytes) + bytesData->size();
		break;
	case ConfigNodeType::Map:
	case ConfigNodeType::DeltaMap:
		result += sizeof(MapType);
		for (auto& e: *mapData) {
			result += e.first.getSizeBytes();
			result += e.second.getSizeBytes();
		}
		break;
	case ConfigNodeType::DeltaSequence:
	case ConfigNodeType::Sequence:
		result += sizeof(SequenceType);
		for (auto& e: *sequenceData) {
			result += e.getSizeBytes();
		}
		break;
	case ConfigNodeType::String:
		result += sizeof(String);
		result += strData->getSizeBytes();
		break;
	}

	return result;
}


text:
package com.yikang.ykmusix.been;

import java.io.Serializable;

public class MusicListingItem implements Serializable {

	private static final long serialVersionUID = 1L;
	int id ;
	String title ;
	int count ;
	int musicListID ;

	public int getMusicListID() {
		return musicListID;
	}
	public void setMusicListID(int musicListID) {
		this.musicListID = musicListID;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}

}


text:
package client

import (
	boshsys "github.com/cloudfoundry/bosh-utils/system"

	"github.com/dpb587/ssoca/client"
	"github.com/dpb587/ssoca/httpclient"

	"github.com/dpb587/ssoca/client/service"
	svc "github.com/dpb587/ssoca/service/file"
	svchttpclient "github.com/dpb587/ssoca/service/file/httpclient"
)

type Service struct {
	svc.ServiceType

	name      string
	runtime   client.Runtime
	fs        boshsys.FileSystem
	cmdRunner boshsys.CmdRunner
}

var _ service.Service = Service{}

func NewService(name string, runtime client.Runtime, fs boshsys.FileSystem, cmdRunner boshsys.CmdRunner) *Service {
	return &Service{
		name:      name,
		runtime:   runtime,
		fs:        fs,
		cmdRunner: cmdRunner,
	}
}

func (s Service) Name() string {
	return s.name
}

func (s Service) GetClient(skipAuthRetry bool) (svchttpclient.Client, error) {
	var client httpclient.Client
	var err error

	if skipAuthRetry {
		client, err = s.runtime.GetClient()
	} else {
		client, err = s.runtime.GetAuthInterceptClient()
	}

	if err != nil {
		return nil, err
	}

	return svchttpclient.New(client, s.name)
}


text:
GitHub Issues are reserved for actionable bug reports and feature requests.
General questions should be sent to the [InfluxDB mailing list](https://groups.google.com/forum/#!forum/influxdb).

Before opening an issue, search for similar bug reports or feature requests on GitHub Issues.
If no similar issue can be found, fill out either the "Bug Report" or the "Feature Request" section below.
Erase the other section and everything on and above this line.

*Please note, the quickest way to fix a bug is to open a Pull Request.*

## Bug report

### Relevant telegraf.conf:

### System info:

[Include Telegraf version, operating system name, and other relevant details]

### Steps to reproduce:

1. ...
2. ...

### Expected behavior:

### Actual behavior:

### Additional info:

[Include gist of relevant config, logs, etc.]

## Feature Request

Opening a feature request kicks off a discussion.

### Proposal:

### Current behavior:

### Desired behavior:

### Use case: [Why is this important (helps with prioritizing requests)]


text:
import java.util.Arrays;

public class JavaExporter_1 {
  public static String varargExample(String... args) {
    return Arrays.toString(args);
  }
}


text:
package com.blackducksoftware.integration.hub.detect.testutils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.stream.Collectors;

import org.apache.commons.io.FileUtils;
import org.json.JSONException;
import org.skyscreamer.jsonassert.JSONAssert;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.synopsys.integration.util.ResourceUtil;

public class TestUtil {
    private final Gson gson = new GsonBuilder().setPrettyPrinting().create();

    public void testJsonResource(final String expectedResourcePath, final Object object) {
        final String expected = getResourceAsUTF8String(expectedResourcePath);
        final String actual = gson.toJson(object);
        System.out.println(actual);
        testJson(expected, actual);
    }

    public void testJson(final String expectedJson, final String actualJson) {
        try {
            JSONAssert.assertEquals(expectedJson, actualJson, false);
        } catch (final JSONException e) {
            throw new RuntimeException(e);
        }
    }

    public String getResourceAsUTF8String(final String resourcePath) {
        final String data;
        try {
            data = ResourceUtil.getResourceAsString(getClass(), resourcePath, StandardCharsets.UTF_8.toString());
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
        return Arrays.asList(data.split("\r?\n")).stream().collect(Collectors.joining(System.lineSeparator()));
    }

    public InputStream getResourceAsInputStream(final String resourcePath) {
        return getClass().getResourceAsStream(resourcePath);
    }

    public void createExpectedFile(final String resourcePath, final Object expectedObject) {
        final String expectedJson = gson.toJson(expectedObject);
        final File outputFile = new File("src/test/resources", resourcePath);
        outputFile.delete();
        try {
            FileUtils.write(outputFile, expectedJson, StandardCharsets.UTF_8);
        } catch (final IOException e) {
            throw new RuntimeException(e);
        }
    }
}


text:
package pl.zankowski.iextrading4j.api.stocks;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Objects;
import java.util.StringJoiner;

public class TimeSeries implements Serializable {

    private static final long serialVersionUID = -5513479374604990501L;

    private final String symbol;
    private final String id;
    private final String key;
    private final String subkey;
    private final Long updated;
    private final String date;
    private final BigDecimal open;
    private final BigDecimal high;
    private final BigDecimal low;
    private final BigDecimal close;
    private final BigDecimal volume;
    private final BigDecimal uOpen;
    private final BigDecimal uHigh;
    private final BigDecimal uLow;
    private final BigDecimal uClose;
    private final BigDecimal uVolume;
    private final BigDecimal fOpen;
    private final BigDecimal fHigh;
    private final BigDecimal fLow;
    private final BigDecimal fClose;
    private final BigDecimal fVolume;
    private final BigDecimal unadjustedVolume;
    private final BigDecimal change;
    private final BigDecimal changePercent;
    private final BigDecimal vwap;
    private final String label;
    private final BigDecimal changeOverTime;

    @JsonCreator
    public TimeSeries(
            @JsonProperty("symbol") final String symbol,
            @JsonProperty("id") final String id,
            @JsonProperty("key") final String key,
            @JsonProperty("subkey") final String subkey,
            @JsonProperty("updated") final Long updated,
            @JsonProperty("date") final String date,
            @JsonProperty("open") final BigDecimal open,
            @JsonProperty("high") final BigDecimal high,
            @JsonProperty("low") final BigDecimal low,
            @JsonProperty("close") final BigDecimal close,
            @JsonProperty("volume") final BigDecimal volume,
            @JsonProperty("uOpen") final BigDecimal uOpen,
            @JsonProperty("uHigh") final BigDecimal uHigh,
            @JsonProperty("uLow") final BigDecimal uLow,
            @JsonProperty("uClose") final BigDecimal uClose,
            @JsonProperty("uVolume") final BigDecimal uVolume,
            @JsonProperty("fOpen") final BigDecimal fOpen,
            @JsonProperty("fHigh") final BigDecimal fHigh,
            @JsonProperty("fLow") final BigDecimal fLow,
            @JsonProperty("fClose") final BigDecimal fClose,
            @JsonProperty("fVolume") final BigDecimal fVolume,
            @JsonProperty("unadjustedVolume") final BigDecimal unadjustedVolume,
            @JsonProperty("change") final BigDecimal change,
            @JsonProperty("changePercent") final BigDecimal changePercent,
            @JsonProperty("vwap") final BigDecimal vwap,
            @JsonProperty("label") final String label,
            @JsonProperty("changeOverTime") final BigDecimal changeOverTime) {
        this.symbol = symbol;
        this.id = id;
        this.key = key;
        this.subkey = subkey;
        this.updated = updated;
        this.date = date;
        this.open = open;
        this.high = high;
        this.low = low;
        this.close = close;
        this.volume = volume;
        this.uOpen = uOpen;
        this.uHigh = uHigh;
        this.uLow = uLow;
        this.uClose = uClose;
        this.uVolume = uVolume;
        this.fOpen = fOpen;
        this.fHigh = fHigh;
        this.fLow = fLow;
        this.fClose = fClose;
        this.fVolume = fVolume;
        this.unadjustedVolume = unadjustedVolume;
        this.change = change;
        this.changePercent = changePercent;
        this.vwap = vwap;
        this.label = label;
        this.changeOverTime = changeOverTime;
    }

    public String getSymbol() {
        return symbol;
    }

    public String getId() {
        return id;
    }

    public String getKey() {
        return key;
    }

    public String getSubkey() {
        return subkey;
    }

    public Long getUpdated() {
        return updated;
    }

    public String getDate() {
        return date;
    }

    public BigDecimal getOpen() {
        return open;
    }

    public BigDecimal getHigh() {
        return high;
    }

    public BigDecimal getLow() {
        return low;
    }

    public BigDecimal getClose() {
        return close;
    }

    public BigDecimal getVolume() {
        return volume;
    }

    public BigDecimal getuOpen() {
        return uOpen;
    }

    public BigDecimal getuHigh() {
        return uHigh;
    }

    public BigDecimal getuLow() {
        return uLow;
    }

    public BigDecimal getuClose() {
        return uClose;
    }

    public BigDecimal getuVolume() {
        return uVolume;
    }

    public BigDecimal getfOpen() {
        return fOpen;
    }

    public BigDecimal getfHigh() {
        return fHigh;
    }

    public BigDecimal getfLow() {
        return fLow;
    }

    public BigDecimal getfClose() {
        return fClose;
    }

    public BigDecimal getfVolume() {
        return fVolume;
    }

    public BigDecimal getUnadjustedVolume() {
        return unadjustedVolume;
    }

    public BigDecimal getChange() {
        return change;
    }

    public BigDecimal getChangePercent() {
        return changePercent;
    }

    public BigDecimal getVwap() {
        return vwap;
    }

    public String getLabel() {
        return label;
    }

    public BigDecimal getChangeOverTime() {
        return changeOverTime;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final TimeSeries that = (TimeSeries) o;
        return Objects.equals(symbol, that.symbol) && Objects.equals(id, that.id) &&
                Objects.equals(key, that.key) && Objects.equals(subkey, that.subkey) &&
                Objects.equals(updated, that.updated) && Objects.equals(date, that.date) &&
                Objects.equals(open, that.open) && Objects.equals(high, that.high) &&
                Objects.equals(low, that.low) && Objects.equals(close, that.close) &&
                Objects.equals(volume, that.volume) && Objects.equals(uOpen, that.uOpen) &&
                Objects.equals(uHigh, that.uHigh) && Objects.equals(uLow, that.uLow) &&
                Objects.equals(uClose, that.uClose) && Objects.equals(uVolume, that.uVolume) &&
                Objects.equals(fOpen, that.fOpen) && Objects.equals(fHigh, that.fHigh) &&
                Objects.equals(fLow, that.fLow) && Objects.equals(fClose, that.fClose) &&
                Objects.equals(fVolume, that.fVolume) &&
                Objects.equals(unadjustedVolume, that.unadjustedVolume) &&
                Objects.equals(change, that.change) &&
                Objects.equals(changePercent, that.changePercent) && Objects.equals(vwap, that.vwap) &&
                Objects.equals(label, that.label) &&
                Objects.equals(changeOverTime, that.changeOverTime);
    }

    @Override
    public int hashCode() {
        return Objects.hash(symbol, id, key, subkey, updated, date, open, high, low, close, volume, uOpen, uHigh, uLow,
                uClose, uVolume, fOpen, fHigh, fLow, fClose, fVolume, unadjustedVolume, change, changePercent, vwap,
                label, changeOverTime);
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", TimeSeries.class.getSimpleName() + "[", "]")
                .add("symbol='" + symbol + "'")
                .add("id='" + id + "'")
                .add("key='" + key + "'")
                .add("subkey='" + subkey + "'")
                .add("updated=" + updated)
                .add("date='" + date + "'")
                .add("open=" + open)
                .add("high=" + high)
                .add("low=" + low)
                .add("close=" + close)
                .add("volume=" + volume)
                .add("uOpen=" + uOpen)
                .add("uHigh=" + uHigh)
                .add("uLow=" + uLow)
                .add("uClose=" + uClose)
                .add("uVolume=" + uVolume)
                .add("fOpen=" + fOpen)
                .add("fHigh=" + fHigh)
                .add("fLow=" + fLow)
                .add("fClose=" + fClose)
                .add("fVolume=" + fVolume)
                .add("unadjustedVolume=" + unadjustedVolume)
                .add("change=" + change)
                .add("changePercent=" + changePercent)
                .add("vwap=" + vwap)
                .add("label='" + label + "'")
                .add("changeOverTime=" + changeOverTime)
                .toString();
    }
}


text:
@interface LectureLaunchRouterTests : XCTestCase

@property (nonatomic, strong) LectureLaunchRouter *router;
@property (nonatomic, strong) id mockTabBarControllerFactory;
@property (nonatomic, strong) id mockWindow;
@property (nonatomic, strong) id mockStoryboard;

@property (nonatomic, strong) id mockTabBarController;
@property (nonatomic, strong) id mockNavigationController;
@property (nonatomic, strong) id mockTopController;

@end

@implementation LectureLaunchRouterTests

- (void)setUp {
    [super setUp];

    self.mockTabBarControllerFactory = OCMProtocolMock(@protocol(TabBarControllerFactory));
    self.mockWindow = OCMClassMock([UIWindow class]);
    self.mockStoryboard = OCMClassMock([UIStoryboard class]);

    self.router = [[LectureLaunchRouter alloc] initWithTabBarControllerFactory:self.mockTabBarControllerFactory
                                                                        window:self.mockWindow
                                                                    storyboard:self.mockStoryboard];

    self.mockTabBarController = OCMClassMock([UITabBarController class]);
    self.mockNavigationController = OCMClassMock([UINavigationController class]);
    self.mockTopController = OCMClassMock([UIViewController class]);

    OCMStub([self.mockTabBarController selectedViewController]).andReturn(self.mockNavigationController);
    OCMStub([self.mockNavigationController topViewController]).andReturn(self.mockTopController);
}

- (void)tearDown {
    self.router = nil;

    self.mockTabBarControllerFactory = nil;

    [self.mockWindow stopMocking];
    self.mockWindow = nil;

    [self.mockStoryboard stopMocking];
    self.mockStoryboard = nil;

    [self.mockTabBarController stopMocking];
    self.mockTabBarController = nil;

    [self.mockNavigationController stopMocking];
    self.mockNavigationController = nil;

    [self.mockTopController stopMocking];
    self.mockTopController = nil;

    [super tearDown];
}

- (void)testThatRouterOpensEventController {
    // given
    OCMStub([self.mockTabBarControllerFactory obtainPreconfiguredTabBarController]).andReturn(self.mockTabBarController);

    // when
    [self.router openScreenWithData:nil];

    // then
    OCMVerify([self.mockTopController openModuleUsingFactory:OCMOCK_ANY
                                         withTransitionBlock:OCMOCK_ANY]);
}

- (void)testThatRouterUsesWindowRootViewControllerIfAny {
    // given
    OCMStub([self.mockWindow rootViewController]).andReturn(self.mockTabBarController);
    [[self.mockTabBarControllerFactory reject] obtainPreconfiguredTabBarController];

    // when
    [self.router openScreenWithData:nil];

    // then
    OCMVerify([self.mockTopController openModuleUsingFactory:OCMOCK_ANY
                                         withTransitionBlock:OCMOCK_ANY]);
    OCMVerifyAll(self.mockTabBarControllerFactory);
}

@end


text:
# VEI API
The VEI-API is a Virtual Entenerpise International PHP based Web Scraper with the purpose to
  - Retrive the users real name with given credentials
  - Get storemanager data for purchases (via Excel XLSX).

## Requirements
VEI-API  uses a few open source projects to work properly:
* [Goutte] - A Simple Web Scrapper for PHP
* [Spout] - Reading and Writing of CSV, XLSX and ODS files in PHP
* [Guzzle] - It's used by Goutte for html processing. I needed an up to date version.

VEI-API requires [PHP](http://php.net) v5.6+ to execute.

There is a folder called **lib** which contains the composer files I downloaded and used.
>Also in **lib\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php** on like 78, **curl_reset($resource)** was removed because of a PHP version error. This may or may not needed to be removed based on your PHP version.

## Installation

Download and extract the [master.zip](https://github.com/Import-Python/vei-api/archive/master.zip) and exract it.
Install the folder into a directory on your server you wish to use.

Composer is not supported but feel free to use composer on all listed in requirements.

---
# Usage
To get the users real name or other user based data with their credentials you would want to use:
```php
require_once __DIR__ . '/veiAPI.php'; //Require the lib, the path may differ
vei = new VEI(); //Initilize the VEI API
$vei->setCredentials('USERNAME', 'PASSWORD'); //Set users credentials.
$name = $vei->getRealname(); //Get the user realname and store it.
$company = $vei->getCompany(); //Get the user company name. REQUIRES user to have FIRM BANK enabled on account.
$comoany_id = $vei->getCompanyID(); //Get the user company id. REQUIRES user to have FIRM BANK as well.
```
Also below is the purchase data from the XLSX file from the **storemanager** thats for download:
* The first parameter, **URL_ID** its usually found within the storemanager:
  **portal.veinternational.org/storemanager/[URL_ID]/.../**
* The other two are dates, **START_DATE** & **END_DATE**, which need to have the format of date like: *MM/DD/YEAR* or for example **03/09/2016** to **11/13/2016**

```php
require_once __DIR__ . '/veiAPI.php'; //Require the lib, the path differ
vei = new VEI(); //Initilize the VEI API
$vei->setCredentials('USERNAME', 'PASSWORD'); //Set users credentials.
$data = $vei->getExcelDataCustom('URL_ID', 'START_DATE', 'END_DATE'); //DATA
//$data = $vei->getExcelDataYesterday('URL_ID'); //GETS YESTERDAYS PURCHASES
/* Data is now an array which contains all the data listed below*/
```
When using the ExcelData functions, you get this data (in JSON only for readablity)
```JSON
{
  "<TRANSACTION NUMBER>": {
    "dateTime": {
      "date": "0000-00-00 00:00:00.000000",
      "timezone_type": 0,
      "timezone": ""
    },
    "billing_name": "",
    "billing_company": "",
    "billing_address": "",
    "billing_city": "",
    "billing_state": "",
    "billing_zip": "",
    "billing_country": "",
    "shipping_name": ")",
    "shipping_company": "",
    "shipping_address": "",
    "shipping_city": "",
    "shipping_state": "",
    "shipping_zip": "",
    "shipping_country": "",
    "email": "",
    "subtotal": 0,
    "shipping": 0,
    "tax": 0,
    "total": 0,
    "item_name": "",
    "item_number": "",
    "price": 0,
    "quantity": 0,
    "amount": 0
  }
}
```
---
# Practical Uses

I personally used it for getting the user **realname** and then compare the data to role out a automatic reminding system to make sure the pay monthly fees. (I sold Apartments for my firm)

# Upcoming Features:
* Allow for **promotional codes** to be created and removed (storemanager)
* Download all direct deposited money?
* Attendence tracking?
* Overall statics of the portal?

# About
Use at your own risk. If attemping to authenticate users, don't steal passwords and money from the virtual bank.

[//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax)

   [Goutte]: <https://github.com/FriendsOfPhp/Goutte>
   [Spout]: <https://github.com/box/spout>
   [Guzzle]: <https://github.com/guzzle/guzzle>


text:
@interface LocalNotificationManager ()
+ (void)setupNext9;
+ (void)setupAfter3days;
+ (void)setupWhiteDay;
@end

SPEC_BEGIN(LocalNotificationManagerSpec)
describe(@"LocalNotificationManager", ^{
    context(@"application", ^{
        __block UIApplication *application;
        beforeEach(^{
            application = [UIApplication mock];
            [UIApplication stub:@selector(sharedApplication) andReturn:application];
        });
        describe(@"reset", ^{
            context(@"alerm off", ^{
                beforeEach(^{
                    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"alerm"];
                });
                it(@"cancel all", ^{
                    [[application should] receive:@selector(cancelAllLocalNotifications)];

                    [LocalNotificationManager reset];
                });
            });
            context(@"alerm on", ^{
                beforeEach(^{
                    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"alerm"];
                });
                it(@"cancel all", ^{
                    [[application should] receive:@selector(cancelAllLocalNotifications)];
                    [[LocalNotificationManager should] receive:@selector(setupNext9)];
                    [[LocalNotificationManager should] receive:@selector(setupAfter3days)];
                    [[LocalNotificationManager should] receive:@selector(setupWhiteDay)];

                    [LocalNotificationManager reset];
                });
            });
            context(@"receive Alert", ^{
                __block NSMutableArray *notifications;
                __block NSDate *date;
                beforeEach(^{
                    date = [NSDate AZ_dateByUnit:@{
                        AZ_DateUnit.year : @2014,
                        AZ_DateUnit.month : @3,
                        AZ_DateUnit.day : @9,
                        AZ_DateUnit.hour : @12,
                    }];
                    [NSDate stub:@selector(date) andReturn:date];

                    notifications = [NSMutableArray array];
                    [[application should] receive:@selector(cancelAllLocalNotifications)];
                    [application stub:@selector(scheduleLocalNotification:) withBlock:^id(NSArray *params) {
                        [notifications addObject:params[0]];
                        return nil;
                    }];
                    [LocalNotificationManager reset];
                });
                it(@"count", ^{
                    [[theValue(notifications.count) should] equal:theValue(3)];
                });
                it(@"scheduled local notification", ^{
                    for (UILocalNotification *n in notifications) {
                        if ([n.alertBody isEqualToString:@"9時になりました"]) {
                            [[n.fireDate should] equal:[NSDate AZ_dateByUnit:@{
                                AZ_DateUnit.year : @2014,
                                AZ_DateUnit.month : @3,
                                AZ_DateUnit.day : @10,
                                AZ_DateUnit.hour : @9,
                            }]];
                        } else if ([n.alertBody isEqualToString:@"3日経ちました"]) {
                            [[n.fireDate should] equal:[NSDate AZ_dateByUnit:@{
                                AZ_DateUnit.year : @2014,
                                AZ_DateUnit.month : @3,
                                AZ_DateUnit.day : @12,
                                AZ_DateUnit.hour : @12,
                            }]];
                        } else if ([n.alertBody isEqualToString:@"明日はホワイトデー"]) {
                            [[n.fireDate should] equal:[NSDate AZ_dateByUnit:@{
                                AZ_DateUnit.year : @2014,
                                AZ_DateUnit.month : @3,
                                AZ_DateUnit.day : @13,
                                AZ_DateUnit.hour : @9,
                            }]];
                        } else {
                            fail(@"not contein alertBody : %@", n);
                        }
                    }
                });
            });
        });
    });
});
SPEC_END


text:
void
str_echo(int sockfd) {
	ssize_t n;
	char buffer[MAXLINE];
		while((n = read(sockfd, buffer, MAXLINE)) > 0){
			s_write(sockfd,buffer,MAXLINE,true);
		}
}

void
str_cli(FILE *stream, int sockfd)
{
	char sendline[MAXLINE], recvline[MAXLINE];
	while(Fgets(sendline,MAXLINE, stream) != NULL) {
		s_write(sockfd, sendline, strlen(sendline), true);
		if(readline(sockfd, recvline, MAXLINE) == 0) {
			prog_error("server exit prematurely\n",true, errno);
		}
		Fputs(recvline, stdout);
	}
}


text:
using Machine.Specifications;
using System.Linq;

namespace Stripe.Tests
{
    [Behaviors]
    public class customer_behaviors
    {
        protected static StripeCustomerCreateOptions StripeCustomerCreateOptions;
        protected static StripeCustomer StripeCustomer;
        protected static StripePlan StripePlan;
        protected static StripeCoupon StripeCoupon;
        protected static StripeCard StripeCard;

        It should_have_a_new_id = () =>
            StripeCustomer.Id.ShouldNotBeNull();

        It should_have_the_correct_email = () =>
            StripeCustomer.Email.ShouldEqual(StripeCustomerCreateOptions.Email);

        It should_have_the_correct_description = () =>
            StripeCustomer.Description.ShouldEqual(StripeCustomerCreateOptions.Description);

        It should_have_the_correct_livemode = () =>
            StripeCustomer.LiveMode.ShouldEqual(false);

        It should_have_the_correct_currency = () =>
            StripeCustomer.Currency.ShouldEqual(StripePlan.Currency);

        It should_have_the_correct_card_address_line_1 = () =>
            StripeCustomer.StripeCardList.StripeCards.First().AddressLine1.ShouldEqual(StripeCard.AddressLine1);

        It should_have_the_correct_card_address_line_2 = () =>
            StripeCustomer.StripeCardList.StripeCards.First().AddressLine2.ShouldEqual(StripeCard.AddressLine2);

        It should_have_the_correct_card_address_state = () =>
            StripeCustomer.StripeCardList.StripeCards.First().AddressState.ShouldEqual(StripeCard.AddressState);

        It should_have_the_correct_card_address_zip = () =>
            StripeCustomer.StripeCardList.StripeCards.First().AddressZip.ShouldEqual(StripeCard.AddressZip);

        It should_have_the_correct_card_last_4 = () =>
            StripeCustomer.StripeCardList.StripeCards.First().Last4.ShouldEqual(StripeCard.Last4.ShouldEqual(StripeCard.Last4));

        It should_have_the_correct_card_expiration_month = () =>
            StripeCustomer.StripeCardList.StripeCards.First().ExpirationMonth.ShouldEqual(StripeCard.ExpirationMonth);

        It should_have_the_correct_card_expiration_year = () =>
            StripeCustomer.StripeCardList.StripeCards.First().ExpirationYear.ShouldEqual(StripeCard.ExpirationYear);

        It should_have_the_correct_card_name = () =>
            StripeCustomer.StripeCardList.StripeCards.First().Name.ShouldEqual(StripeCard.Name);

        It should_have_the_correct_card_type = () =>
            StripeCustomer.StripeCardList.StripeCards.First().Brand.ShouldEqual("Visa");

        It should_have_the_correct_card_country = () =>
            StripeCustomer.StripeCardList.StripeCards.First().Country.ShouldEqual("US");

        It should_have_the_correct_coupon_id = () =>
            StripeCustomer.StripeDiscount.StripeCoupon.Id.ShouldEqual(StripeCoupon.Id);

        It should_have_the_correct_coupon_percent_off = () =>
            StripeCustomer.StripeDiscount.StripeCoupon.PercentOff.ShouldEqual(StripeCoupon.PercentOff);

        It should_have_the_correct_coupon_duration = () =>
            StripeCustomer.StripeDiscount.StripeCoupon.Duration.ShouldEqual(StripeCoupon.Duration);

        It should_have_the_correct_coupon_duration_in_months = () =>
            StripeCustomer.StripeDiscount.StripeCoupon.DurationInMonths.ShouldEqual(StripeCoupon.DurationInMonths);

        It should_have_the_correct_coupon_max_redemptions = () =>
            StripeCustomer.StripeDiscount.StripeCoupon.MaxRedemptions.ShouldEqual(StripeCoupon.MaxRedemptions);

        It should_have_the_correct_coupon_livemode = () =>
            StripeCustomer.StripeDiscount.StripeCoupon.LiveMode.ShouldEqual(false);
    }
}


text:
INSERT INTO cms_configuration_parameters(module_id, parameter_name, sort_order, parameter_data_type_id, display_name, has_value_list)
VALUES (2, 'hitbox_client_id', 18, 1, 'Hitbox Client ID', 0);

INSERT INTO cms_configuration_parameters(module_id, parameter_name, sort_order, parameter_data_type_id, display_name, has_value_list)
VALUES (2, 'hitbox_client_secret', 19, 1, 'Hitbox Client Secret', 0);


text:
using System;

namespace Common.Validation
{
    [Serializable]
    public class ValidationException : Exception
    {
        public ValidationResult ValidationResult { get; private set; }

        public ValidationException(ValidationResult validationResult) : base(validationResult.ErrorMessage)
        {
            ValidationResult = validationResult;
        }
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2015/2016 The CyanPop Project,Chandra Poerwanto
  ~
  ~ 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.
  -->

<resources>
    <!-- Palette colors referenced by top-level themes. -->
    <color name="theme_primary">#ff263238</color>
    <color name="theme_primary_dark">#ff21272b</color>
    <color name="theme_accent">#ff009688</color>
</resources>


text:
"use strict";

const _ = require('underscore');

const mongodb = require('../util/mongodb');
const Users = require('../models/users');

let watched = {
    users: {},
    journeys: {}
};

const mongoQuery = {
    '_id': 'watched'
};

function toObject(arr) {
    return arr.reduce((obj, val) => {
        obj[val] = true;
        return obj;
    }, {});
}

function toArray(obj) {
    return Object.keys(obj);
}

let loadTimeout = null;

function load() {
    clearTimeout(loadTimeout);
    return mongodb.connect()
        .then(db => db.collection('settings').findOne(mongoQuery))
        .then(results => {
            if (results) {
                watched.users = toObject(results.users);
                watched.journeys = toObject(results.journeys);
            }
        })
        .then(() => loadTimeout = setTimeout(load, (30 * 60 * 1000)))
        .catch(err => console.error("Watch: Could not load watch settings!", err, err.stack));
}

function sync() {
    const prepared = {
        users: toArray(watched.users),
        journeys: toArray(watched.journeys)
    };

    console.log("Syncing watched users/journeys", prepared);
    return mongodb.connect()
        .then(db => db.collection('settings').update(mongoQuery, prepared, {
            upsert: true
        }));
}

function isUserWatched(userID) {
    if (!userID) {
        throw new Error("Missing user ID");
    }
    return (userID in watched.users);
}

function isJourneyWatched(uid, ssd) {
    if (!uid || !ssd) {
        throw new Error("Missing UID or SSD");
    }
    return (`${uid}-${ssd}` in watched.journeys);
}

function pushJourneys(journeys) {
    _.each(journeys, journey => {
        watched.journeys[`${journey.uid}-${journey.ssd}`] = true;
    });
}

function watch(userID) {
    if (isUserWatched(userID)) {
        console.log(`Watch: User ${userID} is already watched`);
        return;
    }
    return Users.find(userID)
        .then(user => {
            if (!user) {
                console.log(`Watch: Could not watch ${userID}, user does not exist`);
            } else {
                watched.users[userID] = true;
                pushJourneys(user.out.journeys);
                pushJourneys(user.return.journeys);
                return sync();
            }
        })
        .then(() => console.log(`Watch: Watched user ${userID}`))
        .catch(err => console.error(`Watch: Error watching user ${userID}`, err));
}

function update() {
    return load().then(() => {
        const users = toArray(watched.users);
        watched.users = {};
        watched.journeys = {};

        return Promise.all(users.map(user => watch(user)));
    }).catch(err => console.log("Derp", err));
}

load();

module.exports = {
    isUserWatched,
    isJourneyWatched,
    watch,
    update
};


text:
from __future__ import print_function
from __future__ import absolute_import

import numpy as np

from nibabel import Nifti1Image
from ..utils.simul_multisubject_fmri_dataset import \
    surrogate_2d_dataset
from ..statistical_mapping import cluster_stats

def make_surrogate_data():
    """ Return a single deterministic 3D image
    """
    shape = (40, 40)
    pos   = np.array([[ 2, 10],
                      [10,  4],
                      [20, 30],
                      [30, 20]])
    ampli = np.array([5, 5, 5, 5])
    data = surrogate_2d_dataset(n_subj=1, pos=pos, shape=shape, noise_level=0,
                                ampli=ampli, spatial_jitter=0,
                                signal_jitter=0).squeeze()
    data = np.reshape(data, (shape[0], shape[1], 1))
    return Nifti1Image(data, np.eye(4))

def test1():
    img = make_surrogate_data()
    clusters, info = cluster_stats(img, img, height_th=3., height_control='None', cluster_th=0, nulls={})
    assert len(clusters)==4

def test2():
    img = make_surrogate_data()
    clusters, info = cluster_stats(img, img, height_th=3., height_control='None', cluster_th=5, nulls={})
    assert len(clusters)==4

def test3():
    img = make_surrogate_data()
    clusters, info = cluster_stats(img, img, height_th=3., height_control='None', cluster_th=10, nulls={})
    assert len(clusters)==0

def test_4():
    img = make_surrogate_data()
    clusters, info = cluster_stats(img, img, height_th=.001, height_control='fpr', cluster_th=0, nulls={})
    assert len(clusters)==4

def test_5():
    img = make_surrogate_data()
    clusters, info = cluster_stats(img, img, height_th=.05, height_control='bonferroni', cluster_th=0, nulls={})
    assert len(clusters)==4

def test_6():
    img = make_surrogate_data()
    clusters, info = cluster_stats(img, img, height_th=.05,
                                   height_control='fdr', cluster_th=0, nulls={})
    print(len(clusters), sum([c['size'] for c in clusters]))
    assert len(clusters)==4

def test7():
    img = make_surrogate_data()
    clusters, info = cluster_stats(img, img, height_th=3., height_control='None', cluster_th=0, nulls={})
    nstv = sum([c['size'] for c in clusters])
    assert nstv==36

def test_8():
    img = make_surrogate_data()
    clusters, info = cluster_stats(img, img, height_th=.001, height_control='fpr', cluster_th=0, nulls={})
    nstv = sum([c['size'] for c in clusters])
    assert nstv==36

if __name__ == "__main__":
    import nose
    nose.run(argv=['', __file__])


text:
<?php

namespace Webiny\Hrc\CacheStorage;

/**
 * Class ArrayCache
 * Note: This cache is not intended for use in production. It's designed to be used in unit tests.
 *
 * @package Webiny\Hrc\CacheStorage
 */
class ArrayCache implements CacheStorageInterface
{
    private $array;

    /**
     * Read the cache for the given key.
     *
     * @param string $key Cache key
     *
     * @return string|bool Cache content, or bool false if the key is not found in the cache.
     */
    public function read($key)
    {
        return isset($this->array[$key]) ? $this->array[$key] : false;
    }

    /**
     * Save the given content into cache.
     *
     * @param string $key     Cache key.
     * @param string $content Content that should be saved.
     * @param string $ttl     Cache time-to-live
     *
     * @return bool
     */
    public function save($key, $content, $ttl)
    {
        $this->array[$key] = $content; // ignore ttl

        return true;
    }

    /**
     * Purge (delete) the given key from cache.
     *
     * @param string $key Cache key that should be deleted.
     *
     * @return bool True if key was found and deleted, otherwise false.
     */
    public function purge($key)
    {
        if (isset($this->array[$key])) {
            unset($this->array[$key]);

            return true;
        }

        return false;
    }

    /**
     * @return int Returns the remaining ttl of the matched cache rule.
     */
    public function getRemainingTtl()
    {
        return 0;
    }
}


text:
<md-content class="md-padding">

      <md-card ng-repeat="room in vm.rooms | orderBy:'room_num'" flex="20">
        <form name="roomUpdateForm">
          <md-card-title>
            <md-card-title-text>
              Room Num: {{ room.room_num }}
              Number of Occupants:{{ room.num_occupants }}

                  <md-input-container ng-if="room.edit" class="md-block">
                    Number of Occupants
                    <input name="name" ng-model="room.num_occupants" type="number" step="any" min="1" max="3" required>

This field is required.

                  </md-input-container>

            </md-card-title-text>
          </md-card-title>

          <md-content layout-padding layout-wrap>

{{ vm.floor_id_to_string(room.floor_id) }}

              <md-input-container ng-if="room.edit" class="md-block">
                Floor Id
                <md-select placeholder="Select Floor" ng-model="room.floor_id" md-on-open="vm.getFloors()">
                     <md-option ng-value="floor.id" ng-repeat="floor in vm.floors">{{ floor.name }}</md-option>
                </md-select>
              </md-input-container>
          </md-content>

          <md-card-actions layout="row" layout-align="end center">
            <md-button ng-click="vm.updateRoom(room)" class="md-primary">{{ room.edit ? "Save" : "Update"}}</md-button>

            <md-button ng-if="room.edit" ng-click="room.edit = false" class="md-warn">Cancel</md-button>
            <md-button ng-if="!room.edit" ng-click="vm.deleteRoom(room)" class="md-warn">{{ room.delete ? "Are you sure?" : "Delete" }}</md-button>
          </md-card-actions>
        </form>
      </md-card>

      <md-card>
        <md-card-title ng-if="!vm.create">
          <md-card-title-text layout="row" layout-align="center">
            <md-button ng-click="vm.createRoom(room)" class="md-headline md-raised md-primary">Create Room</md-button>
          </md-card-title-text>
        </md-card-title>

        <md-content ng-if="vm.create" layout-padding layout-wrap>
          <form name="roomForm">
             <md-input-container class="md-block">
               Room Number
               <input name="floor_num" ng-model="vm.form.room_num" type="number" step="any" min="1" required>

This field is required.

             </md-input-container>

             <md-input-container class="md-block">
               Number of Occupants
               <input name="num_occupants" ng-model="vm.form.num_occupants" type="number" step="any" min="1" max="3" required>

This field is required.

             </md-input-container>

             <md-input-container class="md-block">
               Floor Id
               <md-select placeholder="Select Floor" ng-model="vm.form.floor_id" md-on-open="vm.getFloors()">
                    <md-option ng-value="floor.id" ng-repeat="floor in vm.floors">{{ floor.name }}</md-option>
               </md-select>
             </md-input-container>

                <md-button ng-click="vm.createRoom()" class="md-primary">Create</md-button>
                <md-button ng-click="vm.create = false" class="md-warn">Cancel</md-button>

          </form>
        </md-content>
      </md-card>

  </md-content>


text:
'use strict';

var log = require('loglevel');

module.exports = function ($ctx) {
  log.debug('default.js');
};


text:
package boofcv.alg.geo;

import georegression.geometry.RotationMatrixGenerator;
import georegression.struct.so.Rodrigues_F64;
import org.ddogleg.optimization.DerivativeChecker;
import org.ddogleg.optimization.functions.FunctionNtoM;
import org.ddogleg.optimization.functions.FunctionNtoMxN;
import org.ejml.data.DenseMatrix64F;
import org.ejml.ops.CommonOps;
import org.junit.Test;

import java.util.Random;

import static org.junit.Assert.assertTrue;

/**
 * @author Peter Abeles
 */
public class TestRodriguesRotationGradient {

	Random rand = new Random(234);

	@Test
	public void checkUsingNumerical() {
		RodToMatrix f = new RodToMatrix();
		RodToGradient g = new RodToGradient();

		for( int i = 0; i < 20; i++ ) {
			double param[] = new double[3];
			param[0] = (rand.nextDouble()-0.5);
			param[1] = (rand.nextDouble()-0.5);
			param[2] = (rand.nextDouble()-0.5);

			assertTrue(DerivativeChecker.jacobian(f, g, param, 1e-6));
		}
	}

// Commented out since I'm not sure if numerical or analytical Jacobian is correct
// Potential room for improvement here
//	@Test
//	public void checkHardCases() {
//
//		RodToMatrix f = new RodToMatrix();
//		RodToGradient g = new RodToGradient();
//
//		DerivativeChecker.jacobianPrintR(f, g, new double[]{1e-6,1e-6,1e-6}, 1e-6);
//		assertTrue(DerivativeChecker.jacobianR(f, g, new double[]{1e-6,1e-6,1e-6}, 1e-6));
//	}

	public static class RodToMatrix implements FunctionNtoM
	{
		@Override
		public int getNumOfInputsN() {
			return 3;
		}

		@Override
		public int getNumOfOutputsM() {
			return 9;
		}

		@Override
		public void process(double[] input, double[] output) {
			Rodrigues_F64 r = new Rodrigues_F64();

			r.setParamVector(input[0],input[1],input[2]);
			DenseMatrix64F M = DenseMatrix64F.wrap(3,3,output);

			RotationMatrixGenerator.rodriguesToMatrix(r,M);
		}
	}

	public static class RodToGradient implements FunctionNtoMxN
	{
		@Override
		public int getNumOfInputsN() {
			return 3;
		}

		@Override
		public int getNumOfOutputsM() {
			return 9;
		}

		@Override
		public void process(double[] input, double[] output) {
			RodriguesRotationJacobian g = new RodriguesRotationJacobian();

			g.process(input[0],input[1],input[2]);

			DenseMatrix64F J = DenseMatrix64F.wrap(3,9,output);

			System.arraycopy(g.Rx.data,0,output,0,9);
			System.arraycopy(g.Ry.data,0,output,9,9);
			System.arraycopy(g.Rz.data,0,output,18,9);

			CommonOps.transpose(J);
		}
	}
}