git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce

subrepo:
  subdir:   "deps/juce"
  merged:   "b13f9084e"
upstream:
  origin:   "https://github.com/essej/JUCE.git"
  branch:   "sono6good"
  commit:   "b13f9084e"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
This commit is contained in:
essej
2022-04-18 17:51:22 -04:00
parent 63e175fee6
commit 25bd5d8adb
3210 changed files with 1045392 additions and 0 deletions

View File

@ -0,0 +1,301 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_CodeHelpers.h"
//==============================================================================
namespace CodeHelpers
{
String indent (const String& code, const int numSpaces, bool indentFirstLine)
{
if (numSpaces == 0)
return code;
auto space = String::repeatedString (" ", numSpaces);
auto lines = StringArray::fromLines (code);
for (auto& line : lines)
{
if (! indentFirstLine)
{
indentFirstLine = true;
continue;
}
if (line.trimEnd().isNotEmpty())
line = space + line;
}
return lines.joinIntoString (newLine);
}
String unindent (const String& code, const int numSpaces)
{
if (numSpaces == 0)
return code;
auto space = String::repeatedString (" ", numSpaces);
auto lines = StringArray::fromLines (code);
for (auto& line : lines)
if (line.startsWith (space))
line = line.substring (numSpaces);
return lines.joinIntoString (newLine);
}
String createIncludeStatement (const File& includeFile, const File& targetFile)
{
return createIncludeStatement (build_tools::unixStylePath (build_tools::getRelativePathFrom (includeFile, targetFile.getParentDirectory())));
}
String createIncludeStatement (const String& includePath)
{
if (includePath.startsWithChar ('<') || includePath.startsWithChar ('"'))
return "#include " + includePath;
return "#include \"" + includePath + "\"";
}
String createIncludePathIncludeStatement (const String& includedFilename)
{
return "#include <" + includedFilename + ">";
}
String stringLiteral (const String& text, int maxLineLength)
{
if (text.isEmpty())
return "juce::String()";
StringArray lines;
{
auto t = text.getCharPointer();
bool finished = t.isEmpty();
while (! finished)
{
for (auto startOfLine = t;;)
{
switch (t.getAndAdvance())
{
case 0: finished = true; break;
case '\n': break;
case '\r': if (*t == '\n') ++t; break;
default: continue;
}
lines.add (String (startOfLine, t));
break;
}
}
}
if (maxLineLength > 0)
{
for (int i = 0; i < lines.size(); ++i)
{
auto& line = lines.getReference (i);
if (line.length() > maxLineLength)
{
const String start (line.substring (0, maxLineLength));
const String end (line.substring (maxLineLength));
line = start;
lines.insert (i + 1, end);
}
}
}
for (int i = 0; i < lines.size(); ++i)
lines.getReference(i) = CppTokeniserFunctions::addEscapeChars (lines.getReference(i));
lines.removeEmptyStrings();
for (int i = 0; i < lines.size(); ++i)
lines.getReference(i) = "\"" + lines.getReference(i) + "\"";
String result (lines.joinIntoString (newLine));
if (! CharPointer_ASCII::isValidString (text.toUTF8(), std::numeric_limits<int>::max()))
result = "juce::CharPointer_UTF8 (" + result + ")";
return result;
}
String alignFunctionCallParams (const String& call, const StringArray& parameters, const int maxLineLength)
{
String result, currentLine (call);
for (int i = 0; i < parameters.size(); ++i)
{
if (currentLine.length() >= maxLineLength)
{
result += currentLine.trimEnd() + newLine;
currentLine = String::repeatedString (" ", call.length()) + parameters[i];
}
else
{
currentLine += parameters[i];
}
if (i < parameters.size() - 1)
currentLine << ", ";
}
return result + currentLine.trimEnd() + ")";
}
String floatLiteral (double value, int numDecPlaces)
{
String s (value, numDecPlaces);
if (s.containsChar ('.'))
s << 'f';
else
s << ".0f";
return s;
}
String boolLiteral (bool value)
{
return value ? "true" : "false";
}
String colourToCode (Colour col)
{
const Colour colours[] =
{
#define COL(col) Colours::col,
#include "jucer_Colours.h"
#undef COL
Colours::transparentBlack
};
static const char* colourNames[] =
{
#define COL(col) #col,
#include "jucer_Colours.h"
#undef COL
nullptr
};
for (int i = 0; i < numElementsInArray (colourNames) - 1; ++i)
if (col == colours[i])
return "juce::Colours::" + String (colourNames[i]);
return "juce::Colour (0x" + build_tools::hexString8Digits ((int) col.getARGB()) + ')';
}
String justificationToCode (Justification justification)
{
switch (justification.getFlags())
{
case Justification::centred: return "juce::Justification::centred";
case Justification::centredLeft: return "juce::Justification::centredLeft";
case Justification::centredRight: return "juce::Justification::centredRight";
case Justification::centredTop: return "juce::Justification::centredTop";
case Justification::centredBottom: return "juce::Justification::centredBottom";
case Justification::topLeft: return "juce::Justification::topLeft";
case Justification::topRight: return "juce::Justification::topRight";
case Justification::bottomLeft: return "juce::Justification::bottomLeft";
case Justification::bottomRight: return "juce::Justification::bottomRight";
case Justification::left: return "juce::Justification::left";
case Justification::right: return "juce::Justification::right";
case Justification::horizontallyCentred: return "juce::Justification::horizontallyCentred";
case Justification::top: return "juce::Justification::top";
case Justification::bottom: return "juce::Justification::bottom";
case Justification::verticallyCentred: return "juce::Justification::verticallyCentred";
case Justification::horizontallyJustified: return "juce::Justification::horizontallyJustified";
default: break;
}
jassertfalse;
return "Justification (" + String (justification.getFlags()) + ")";
}
//==============================================================================
String getLeadingWhitespace (String line)
{
line = line.removeCharacters (line.endsWith ("\r\n") ? "\r\n" : "\n");
auto endOfLeadingWS = line.getCharPointer().findEndOfWhitespace();
return String (line.getCharPointer(), endOfLeadingWS);
}
int getBraceCount (String::CharPointerType line)
{
int braces = 0;
for (;;)
{
const juce_wchar c = line.getAndAdvance();
if (c == 0) break;
else if (c == '{') ++braces;
else if (c == '}') --braces;
else if (c == '/') { if (*line == '/') break; }
else if (c == '"' || c == '\'') { while (! (line.isEmpty() || line.getAndAdvance() == c)) {} }
}
return braces;
}
bool getIndentForCurrentBlock (CodeDocument::Position pos, const String& tab,
String& blockIndent, String& lastLineIndent)
{
int braceCount = 0;
bool indentFound = false;
while (pos.getLineNumber() > 0)
{
pos = pos.movedByLines (-1);
auto line = pos.getLineText();
auto trimmedLine = line.trimStart();
braceCount += getBraceCount (trimmedLine.getCharPointer());
if (braceCount > 0)
{
blockIndent = getLeadingWhitespace (line);
if (! indentFound)
lastLineIndent = blockIndent + tab;
return true;
}
if ((! indentFound) && trimmedLine.isNotEmpty())
{
indentFound = true;
lastLineIndent = getLeadingWhitespace (line);
}
}
return false;
}
}

View File

@ -0,0 +1,52 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
namespace CodeHelpers
{
String indent (const String& code, int numSpaces, bool indentFirstLine);
String unindent (const String& code, int numSpaces);
String createIncludeStatement (const File& includedFile, const File& targetFile);
String createIncludeStatement (const String& includePath);
String createIncludePathIncludeStatement (const String& includedFilename);
String stringLiteral (const String& text, int maxLineLength = -1);
String floatLiteral (double value, int numDecPlaces);
String boolLiteral (bool value);
String colourToCode (Colour);
String justificationToCode (Justification);
String alignFunctionCallParams (const String& call, const StringArray& parameters, int maxLineLength);
String getLeadingWhitespace (String line);
int getBraceCount (String::CharPointerType line);
bool getIndentForCurrentBlock (CodeDocument::Position pos, const String& tab,
String& blockIndent, String& lastLineIndent);
}

View File

@ -0,0 +1,162 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
COL(black)
COL(white)
COL(blue)
COL(grey)
COL(green)
COL(red)
COL(yellow)
COL(aliceblue)
COL(antiquewhite)
COL(aqua)
COL(aquamarine)
COL(azure)
COL(beige)
COL(bisque)
COL(blanchedalmond)
COL(blueviolet)
COL(brown)
COL(burlywood)
COL(cadetblue)
COL(chartreuse)
COL(chocolate)
COL(coral)
COL(cornflowerblue)
COL(cornsilk)
COL(crimson)
COL(cyan)
COL(darkblue)
COL(darkcyan)
COL(darkgoldenrod)
COL(darkgrey)
COL(darkgreen)
COL(darkkhaki)
COL(darkmagenta)
COL(darkolivegreen)
COL(darkorange)
COL(darkorchid)
COL(darkred)
COL(darksalmon)
COL(darkseagreen)
COL(darkslateblue)
COL(darkslategrey)
COL(darkturquoise)
COL(darkviolet)
COL(deeppink)
COL(deepskyblue)
COL(dimgrey)
COL(dodgerblue)
COL(firebrick)
COL(floralwhite)
COL(forestgreen)
COL(fuchsia)
COL(gainsboro)
COL(gold)
COL(goldenrod)
COL(greenyellow)
COL(honeydew)
COL(hotpink)
COL(indianred)
COL(indigo)
COL(ivory)
COL(khaki)
COL(lavender)
COL(lavenderblush)
COL(lemonchiffon)
COL(lightblue)
COL(lightcoral)
COL(lightcyan)
COL(lightgoldenrodyellow)
COL(lightgreen)
COL(lightgrey)
COL(lightpink)
COL(lightsalmon)
COL(lightseagreen)
COL(lightskyblue)
COL(lightslategrey)
COL(lightsteelblue)
COL(lightyellow)
COL(lime)
COL(limegreen)
COL(linen)
COL(magenta)
COL(maroon)
COL(mediumaquamarine)
COL(mediumblue)
COL(mediumorchid)
COL(mediumpurple)
COL(mediumseagreen)
COL(mediumslateblue)
COL(mediumspringgreen)
COL(mediumturquoise)
COL(mediumvioletred)
COL(midnightblue)
COL(mintcream)
COL(mistyrose)
COL(navajowhite)
COL(navy)
COL(oldlace)
COL(olive)
COL(olivedrab)
COL(orange)
COL(orangered)
COL(orchid)
COL(palegoldenrod)
COL(palegreen)
COL(paleturquoise)
COL(palevioletred)
COL(papayawhip)
COL(peachpuff)
COL(peru)
COL(pink)
COL(plum)
COL(powderblue)
COL(purple)
COL(rosybrown)
COL(royalblue)
COL(saddlebrown)
COL(salmon)
COL(sandybrown)
COL(seagreen)
COL(seashell)
COL(sienna)
COL(silver)
COL(skyblue)
COL(slateblue)
COL(slategrey)
COL(snow)
COL(springgreen)
COL(steelblue)
COL(tan)
COL(teal)
COL(thistle)
COL(tomato)
COL(turquoise)
COL(violet)
COL(wheat)
COL(whitesmoke)
COL(yellowgreen)

View File

@ -0,0 +1,107 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_CodeHelpers.h"
//==============================================================================
namespace FileHelpers
{
bool containsAnyNonHiddenFiles (const File& folder)
{
for (const auto& di : RangedDirectoryIterator (folder, false))
if (! di.getFile().isHidden())
return true;
return false;
}
bool shouldPathsBeRelative (String path1, String path2)
{
path1 = build_tools::unixStylePath (path1);
path2 = build_tools::unixStylePath (path2);
const int len = jmin (path1.length(), path2.length());
int commonBitLength = 0;
for (int i = 0; i < len; ++i)
{
if (CharacterFunctions::toLowerCase (path1[i]) != CharacterFunctions::toLowerCase (path2[i]))
break;
++commonBitLength;
}
return path1.substring (0, commonBitLength).removeCharacters ("/:").isNotEmpty();
}
// removes "/../" bits from the middle of the path
String simplifyPath (String::CharPointerType p)
{
#if JUCE_WINDOWS
if (CharacterFunctions::indexOf (p, CharPointer_ASCII ("/../")) >= 0
|| CharacterFunctions::indexOf (p, CharPointer_ASCII ("\\..\\")) >= 0)
#else
if (CharacterFunctions::indexOf (p, CharPointer_ASCII ("/../")) >= 0)
#endif
{
StringArray toks;
#if JUCE_WINDOWS
toks.addTokens (p, "\\/", StringRef());
#else
toks.addTokens (p, "/", StringRef());
#endif
while (toks[0] == ".")
toks.remove (0);
for (int i = 1; i < toks.size(); ++i)
{
if (toks[i] == ".." && toks [i - 1] != "..")
{
toks.removeRange (i - 1, 2);
i = jmax (0, i - 2);
}
}
return toks.joinIntoString ("/");
}
return p;
}
String simplifyPath (const String& path)
{
#if JUCE_WINDOWS
if (path.contains ("\\..\\") || path.contains ("/../"))
#else
if (path.contains ("/../"))
#endif
return simplifyPath (path.getCharPointer());
return path;
}
}

View File

@ -0,0 +1,79 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
namespace FileHelpers
{
bool containsAnyNonHiddenFiles (const File& folder);
bool shouldPathsBeRelative (String path1, String path2);
// removes "/../" bits from the middle of the path
String simplifyPath (String::CharPointerType path);
String simplifyPath (const String& path);
}
//==============================================================================
const char* const sourceFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;asm;r";
const char* const headerFileExtensions = "h;hpp;hxx;hh;inl";
const char* const cOrCppFileExtensions = "cpp;cc;cxx;c";
const char* const cppFileExtensions = "cpp;cc;cxx";
const char* const objCFileExtensions = "mm;m";
const char* const asmFileExtensions = "s;S;asm";
const char* const sourceOrHeaderFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl";
const char* const browseableFileExtensions = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;h;hpp;hxx;hh;inl;txt;md;rtf";
const char* const fileTypesToCompileByDefault = "cpp;mm;m;metal;c;cc;cxx;swift;s;S;asm;r";
//==============================================================================
struct FileModificationDetector
{
FileModificationDetector (const File& f) : file (f) {}
const File& getFile() const { return file; }
void fileHasBeenRenamed (const File& newFile) { file = newFile; }
bool hasBeenModified() const
{
return fileModificationTime != file.getLastModificationTime()
&& (fileSize != file.getSize()
|| build_tools::calculateFileHashCode (file) != fileHashCode);
}
void updateHash()
{
fileModificationTime = file.getLastModificationTime();
fileSize = file.getSize();
fileHashCode = build_tools::calculateFileHashCode (file);
}
private:
File file;
Time fileModificationTime;
uint64 fileHashCode = 0;
int64 fileSize = -1;
};

View File

@ -0,0 +1,501 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
//==============================================================================
String joinLinesIntoSourceFile (StringArray& lines)
{
while (lines.size() > 10 && lines [lines.size() - 1].isEmpty())
lines.remove (lines.size() - 1);
return lines.joinIntoString (getPreferredLineFeed()) + getPreferredLineFeed();
}
String replaceLineFeeds (const String& content, const String& lineFeed)
{
StringArray lines;
lines.addLines (content);
return lines.joinIntoString (lineFeed);
}
String getLineFeedForFile (const String& fileContent)
{
auto t = fileContent.getCharPointer();
while (! t.isEmpty())
{
switch (t.getAndAdvance())
{
case 0: break;
case '\n': return "\n";
case '\r': if (*t == '\n') return "\r\n";
default: continue;
}
}
return {};
}
String trimCommentCharsFromStartOfLine (const String& line)
{
return line.trimStart().trimCharactersAtStart ("*/").trimStart();
}
String createAlphaNumericUID()
{
String uid;
const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random r;
uid << chars[r.nextInt (52)]; // make sure the first character is always a letter
for (int i = 5; --i >= 0;)
{
r.setSeedRandomly();
uid << chars [r.nextInt (62)];
}
return uid;
}
String createGUID (const String& seed)
{
auto hex = MD5 ((seed + "_guidsalt").toUTF8()).toHexString().toUpperCase();
return "{" + hex.substring (0, 8)
+ "-" + hex.substring (8, 12)
+ "-" + hex.substring (12, 16)
+ "-" + hex.substring (16, 20)
+ "-" + hex.substring (20, 32)
+ "}";
}
String escapeSpaces (const String& s)
{
return s.replace (" ", "\\ ");
}
String escapeQuotesAndSpaces (const String& s)
{
return escapeSpaces (s).replace ("'", "\\'").replace ("\"", "\\\"");
}
String addQuotesIfContainsSpaces (const String& text)
{
return (text.containsChar (' ') && ! text.isQuotedString()) ? text.quoted() : text;
}
void setValueIfVoid (Value value, const var& defaultValue)
{
if (value.getValue().isVoid())
value = defaultValue;
}
//==============================================================================
StringPairArray parsePreprocessorDefs (const String& text)
{
StringPairArray result;
auto s = text.getCharPointer();
while (! s.isEmpty())
{
String token, value;
s.incrementToEndOfWhitespace();
while ((! s.isEmpty()) && *s != '=' && ! s.isWhitespace())
token << s.getAndAdvance();
s.incrementToEndOfWhitespace();
if (*s == '=')
{
++s;
while ((! s.isEmpty()) && *s == ' ')
++s;
while ((! s.isEmpty()) && ! s.isWhitespace())
{
if (*s == ',')
{
++s;
break;
}
if (*s == '\\' && (s[1] == ' ' || s[1] == ','))
++s;
value << s.getAndAdvance();
}
}
if (token.isNotEmpty())
result.set (token, value);
}
return result;
}
StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs)
{
for (int i = 0; i < overridingDefs.size(); ++i)
inheritedDefs.set (overridingDefs.getAllKeys()[i], overridingDefs.getAllValues()[i]);
return inheritedDefs;
}
String createGCCPreprocessorFlags (const StringPairArray& defs)
{
String s;
for (int i = 0; i < defs.size(); ++i)
{
auto def = defs.getAllKeys()[i];
auto value = defs.getAllValues()[i];
if (value.isNotEmpty())
def << "=" << value;
s += " \"" + ("-D" + def).replace ("\"", "\\\"") + "\"";
}
return s;
}
StringArray getSearchPathsFromString (const String& searchPath)
{
StringArray s;
s.addTokens (searchPath, ";\r\n", StringRef());
return getCleanedStringArray (s);
}
StringArray getCommaOrWhitespaceSeparatedItems (const String& sourceString)
{
StringArray s;
s.addTokens (sourceString, ", \t\r\n", StringRef());
return getCleanedStringArray (s);
}
StringArray getCleanedStringArray (StringArray s)
{
s.trim();
s.removeEmptyStrings();
return s;
}
//==============================================================================
void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX, bool scrollY)
{
if (Viewport* const viewport = e.eventComponent->findParentComponentOfClass<Viewport>())
{
const MouseEvent e2 (e.getEventRelativeTo (viewport));
viewport->autoScroll (scrollX ? e2.x : 20, scrollY ? e2.y : 20, 8, 16);
}
}
//==============================================================================
int indexOfLineStartingWith (const StringArray& lines, const String& text, int index)
{
const int len = text.length();
for (const String* i = lines.begin() + index, * const e = lines.end(); i < e; ++i)
{
if (CharacterFunctions::compareUpTo (i->getCharPointer().findEndOfWhitespace(),
text.getCharPointer(), len) == 0)
return index;
++index;
}
return -1;
}
//==============================================================================
bool fileNeedsCppSyntaxHighlighting (const File& file)
{
if (file.hasFileExtension (sourceOrHeaderFileExtensions))
return true;
// This is a bit of a bodge to deal with libc++ headers with no extension..
char fileStart[128] = { 0 };
FileInputStream fin (file);
fin.read (fileStart, sizeof (fileStart) - 4);
return CharPointer_UTF8::isValidString (fileStart, sizeof (fileStart))
&& String (fileStart).trimStart().startsWith ("// -*- C++ -*-");
}
//==============================================================================
void writeAutoGenWarningComment (OutputStream& outStream)
{
outStream << "/*" << newLine << newLine
<< " IMPORTANT! This file is auto-generated each time you save your" << newLine
<< " project - if you alter its contents, your changes may be overwritten!" << newLine
<< newLine;
}
//==============================================================================
StringArray getJUCEModules() noexcept
{
static StringArray juceModuleIds =
{
"juce_analytics",
"juce_audio_basics",
"juce_audio_devices",
"juce_audio_formats",
"juce_audio_plugin_client",
"juce_audio_processors",
"juce_audio_utils",
"juce_box2d",
"juce_core",
"juce_cryptography",
"juce_data_structures",
"juce_dsp",
"juce_events",
"juce_graphics",
"juce_gui_basics",
"juce_gui_extra",
"juce_opengl",
"juce_osc",
"juce_product_unlocking",
"juce_video"
};
return juceModuleIds;
}
bool isJUCEModule (const String& moduleID) noexcept
{
return getJUCEModules().contains (moduleID);
}
StringArray getModulesRequiredForConsole() noexcept
{
return
{
"juce_core",
"juce_data_structures",
"juce_events"
};
}
StringArray getModulesRequiredForComponent() noexcept
{
return
{
"juce_core",
"juce_data_structures",
"juce_events",
"juce_graphics",
"juce_gui_basics"
};
}
StringArray getModulesRequiredForAudioProcessor() noexcept
{
return
{
"juce_audio_basics",
"juce_audio_devices",
"juce_audio_formats",
"juce_audio_plugin_client",
"juce_audio_processors",
"juce_audio_utils",
"juce_core",
"juce_data_structures",
"juce_events",
"juce_graphics",
"juce_gui_basics",
"juce_gui_extra"
};
}
bool isPIPFile (const File& file) noexcept
{
for (auto line : StringArray::fromLines (file.loadFileAsString()))
{
auto trimmedLine = trimCommentCharsFromStartOfLine (line);
if (trimmedLine.startsWith ("BEGIN_JUCE_PIP_METADATA"))
return true;
}
return false;
}
bool isValidJUCEExamplesDirectory (const File& directory) noexcept
{
if (! directory.exists() || ! directory.isDirectory() || ! directory.containsSubDirectories())
return false;
return directory.getChildFile ("Assets").getChildFile ("juce_icon.png").existsAsFile();
}
bool isJUCEFolder (const File& f)
{
return isJUCEModulesFolder (f.getChildFile ("modules"));
}
bool isJUCEModulesFolder (const File& f)
{
return f.isDirectory() && f.getChildFile ("juce_core").isDirectory();
}
//==============================================================================
static bool isDivider (const String& line)
{
auto afterIndent = line.trim();
if (afterIndent.startsWith ("//") && afterIndent.length() > 20)
{
afterIndent = afterIndent.substring (5);
if (afterIndent.containsOnly ("=")
|| afterIndent.containsOnly ("/")
|| afterIndent.containsOnly ("-"))
{
return true;
}
}
return false;
}
static int getIndexOfCommentBlockStart (const StringArray& lines, int endIndex)
{
auto endLine = lines[endIndex];
if (endLine.contains ("*/"))
{
for (int i = endIndex; i >= 0; --i)
if (lines[i].contains ("/*"))
return i;
}
if (endLine.trim().startsWith ("//") && ! isDivider (endLine))
{
for (int i = endIndex; i >= 0; --i)
if (! lines[i].startsWith ("//") || isDivider (lines[i]))
return i + 1;
}
return -1;
}
int findBestLineToScrollToForClass (StringArray lines, const String& className, bool isPlugin)
{
for (auto line : lines)
{
if (line.contains ("struct " + className) || line.contains ("class " + className)
|| (isPlugin && line.contains ("public AudioProcessor") && ! line.contains ("AudioProcessorEditor")))
{
auto index = lines.indexOf (line);
auto commentBlockStartIndex = getIndexOfCommentBlockStart (lines, index - 1);
if (commentBlockStartIndex != -1)
index = commentBlockStartIndex;
if (isDivider (lines[index - 1]))
index -= 1;
return index;
}
}
return 0;
}
//==============================================================================
static var parseJUCEHeaderMetadata (const StringArray& lines)
{
auto* o = new DynamicObject();
var result (o);
for (auto& line : lines)
{
auto trimmedLine = trimCommentCharsFromStartOfLine (line);
auto colon = trimmedLine.indexOfChar (':');
if (colon >= 0)
{
auto key = trimmedLine.substring (0, colon).trim();
auto value = trimmedLine.substring (colon + 1).trim();
o->setProperty (key, value);
}
}
return result;
}
static String parseMetadataItem (const StringArray& lines, int& index)
{
String result = lines[index++];
while (index < lines.size())
{
auto continuationLine = trimCommentCharsFromStartOfLine (lines[index]);
if (continuationLine.isEmpty() || continuationLine.indexOfChar (':') != -1
|| continuationLine.startsWith ("END_JUCE_"))
break;
result += " " + continuationLine;
++index;
}
return result;
}
var parseJUCEHeaderMetadata (const File& file)
{
StringArray lines;
file.readLines (lines);
for (int i = 0; i < lines.size(); ++i)
{
auto trimmedLine = trimCommentCharsFromStartOfLine (lines[i]);
if (trimmedLine.startsWith ("BEGIN_JUCE_"))
{
StringArray desc;
auto j = i + 1;
while (j < lines.size())
{
if (trimCommentCharsFromStartOfLine (lines[j]).startsWith ("END_JUCE_"))
return parseJUCEHeaderMetadata (desc);
desc.add (parseMetadataItem (lines, j));
}
}
}
return {};
}

View File

@ -0,0 +1,134 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
const char* getPreferredLineFeed();
String joinLinesIntoSourceFile (StringArray& lines);
String replaceLineFeeds (const String& content, const String& lineFeed);
String getLineFeedForFile (const String& fileContent);
var parseJUCEHeaderMetadata (const File&);
String trimCommentCharsFromStartOfLine (const String& line);
String createAlphaNumericUID();
String createGUID (const String& seed); // Turns a seed into a windows GUID
String escapeSpaces (const String& text); // replaces spaces with blackslash-space
String escapeQuotesAndSpaces (const String& text);
String addQuotesIfContainsSpaces (const String& text);
StringPairArray parsePreprocessorDefs (const String& defs);
StringPairArray mergePreprocessorDefs (StringPairArray inheritedDefs, const StringPairArray& overridingDefs);
String createGCCPreprocessorFlags (const StringPairArray& defs);
StringArray getCleanedStringArray (StringArray);
StringArray getSearchPathsFromString (const String& searchPath);
StringArray getCommaOrWhitespaceSeparatedItems (const String&);
void setValueIfVoid (Value value, const var& defaultValue);
bool fileNeedsCppSyntaxHighlighting (const File& file);
void writeAutoGenWarningComment (OutputStream& outStream);
StringArray getJUCEModules() noexcept;
bool isJUCEModule (const String& moduleID) noexcept;
StringArray getModulesRequiredForConsole() noexcept;
StringArray getModulesRequiredForComponent() noexcept;
StringArray getModulesRequiredForAudioProcessor() noexcept;
bool isPIPFile (const File&) noexcept;
int findBestLineToScrollToForClass (StringArray, const String&, bool isPlugin = false);
bool isValidJUCEExamplesDirectory (const File&) noexcept;
bool isJUCEModulesFolder (const File&);
bool isJUCEFolder (const File&);
//==============================================================================
int indexOfLineStartingWith (const StringArray& lines, const String& text, int startIndex);
void autoScrollForMouseEvent (const MouseEvent& e, bool scrollX = true, bool scrollY = true);
//==============================================================================
struct PropertyListBuilder
{
void add (PropertyComponent* propertyComp)
{
components.add (propertyComp);
}
void add (PropertyComponent* propertyComp, const String& tooltip)
{
propertyComp->setTooltip (tooltip);
add (propertyComp);
}
void addSearchPathProperty (const Value& value, const String& name, const String& mainHelpText)
{
add (new TextPropertyComponent (value, name, 16384, true),
mainHelpText + " Use semi-colons or new-lines to separate multiple paths.");
}
void addSearchPathProperty (ValueWithDefault& value, const String& name, const String& mainHelpText)
{
add (new TextPropertyComponent (value, name, 16384, true),
mainHelpText + " Use semi-colons or new-lines to separate multiple paths.");
}
void setPreferredHeight (int height)
{
for (int j = components.size(); --j >= 0;)
components.getUnchecked(j)->setPreferredHeight (height);
}
Array<PropertyComponent*> components;
};
//==============================================================================
// A ValueSource which takes an input source, and forwards any changes in it.
// This class is a handy way to create sources which re-map a value.
class ValueSourceFilter : public Value::ValueSource,
private Value::Listener
{
public:
ValueSourceFilter (const Value& source) : sourceValue (source)
{
sourceValue.addListener (this);
}
protected:
Value sourceValue;
private:
void valueChanged (Value&) override { sendChangeMessage (true); }
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueSourceFilter)
};

View File

@ -0,0 +1,296 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_NewFileWizard.h"
//==============================================================================
namespace
{
static String fillInBasicTemplateFields (const File& file, const Project::Item& item, const char* templateName)
{
int dataSize;
if (auto* data = BinaryData::getNamedResource (templateName, dataSize))
{
auto fileTemplate = String::fromUTF8 (data, dataSize);
return replaceLineFeeds (fileTemplate.replace ("%%filename%%", file.getFileName(), false)
.replace ("%%date%%", Time::getCurrentTime().toString (true, true, true), false)
.replace ("%%author%%", SystemStats::getFullUserName(), false)
.replace ("%%include_corresponding_header%%", CodeHelpers::createIncludeStatement (file.withFileExtension (".h"), file)),
item.project.getProjectLineFeed());
}
jassertfalse;
return {};
}
static bool fillInNewCppFileTemplate (const File& file, const Project::Item& item, const char* templateName)
{
return build_tools::overwriteFileWithNewDataIfDifferent (file, fillInBasicTemplateFields (file, item, templateName));
}
const int menuBaseID = 0x12d83f0;
}
//==============================================================================
class NewCppFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "CPP File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.cpp", "*.cpp", parent, [parent] (File newFile)
{
if (newFile != File())
create (parent, newFile, "jucer_NewCppFileTemplate_cpp");
});
}
static bool create (Project::Item parent, const File& newFile, const char* templateName)
{
if (fillInNewCppFileTemplate (newFile, parent, templateName))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
};
//==============================================================================
class NewHeaderFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "Header File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.h", "*.h", parent, [parent] (File newFile)
{
if (newFile != File())
create (parent, newFile, "jucer_NewCppFileTemplate_h");
});
}
static bool create (Project::Item parent, const File& newFile, const char* templateName)
{
if (fillInNewCppFileTemplate (newFile, parent, templateName))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
};
//==============================================================================
class NewCppAndHeaderFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "CPP & Header File"; }
void createNewFile (Project&, Project::Item parent) override
{
askUserToChooseNewFile ("SourceCode.h", "*.h;*.cpp", parent, [parent] (File newFile)
{
if (NewCppFileWizard::create (parent, newFile.withFileExtension ("h"), "jucer_NewCppFileTemplate_h"))
NewCppFileWizard::create (parent, newFile.withFileExtension ("cpp"), "jucer_NewCppFileTemplate_cpp");
});
}
};
//==============================================================================
class NewComponentFileWizard : public NewFileWizard::Type
{
public:
String getName() override { return "Component class (split between a CPP & header)"; }
void createNewFile (Project&, Project::Item parent) override
{
createNewFileInternal (parent);
}
static bool create (const String& className, Project::Item parent,
const File& newFile, const char* templateName)
{
auto content = fillInBasicTemplateFields (newFile, parent, templateName)
.replace ("%%component_class%%", className)
.replace ("%%include_juce%%", CodeHelpers::createIncludePathIncludeStatement (Project::getJuceSourceHFilename()));
content = replaceLineFeeds (content, parent.project.getProjectLineFeed());
if (build_tools::overwriteFileWithNewDataIfDifferent (newFile, content))
{
parent.addFileRetainingSortOrder (newFile, true);
return true;
}
showFailedToWriteMessage (newFile);
return false;
}
private:
virtual void createFiles (Project::Item parent, const String& className, const File& newFile)
{
if (create (className, parent, newFile.withFileExtension ("h"), "jucer_NewComponentTemplate_h"))
create (className, parent, newFile.withFileExtension ("cpp"), "jucer_NewComponentTemplate_cpp");
}
static String getClassNameFieldName() { return "Class Name"; }
void createNewFileInternal (Project::Item parent)
{
asyncAlertWindow = std::make_unique<AlertWindow> (TRANS ("Create new Component class"),
TRANS ("Please enter the name for the new class"),
MessageBoxIconType::NoIcon, nullptr);
asyncAlertWindow->addTextEditor (getClassNameFieldName(), String(), String(), false);
asyncAlertWindow->addButton (TRANS ("Create Files"), 1, KeyPress (KeyPress::returnKey));
asyncAlertWindow->addButton (TRANS ("Cancel"), 0, KeyPress (KeyPress::escapeKey));
auto resultCallback = [safeThis = WeakReference<NewComponentFileWizard> { this }, parent] (int result)
{
if (safeThis == nullptr)
return;
auto& aw = *(safeThis->asyncAlertWindow);
aw.exitModalState (result);
aw.setVisible (false);
if (result == 0)
return;
const String className (aw.getTextEditorContents (getClassNameFieldName()).trim());
if (className == build_tools::makeValidIdentifier (className, false, true, false))
{
safeThis->askUserToChooseNewFile (className + ".h", "*.h;*.cpp",
parent,
[safeThis, parent, className] (File newFile)
{
if (safeThis == nullptr)
return;
if (newFile != File())
safeThis->createFiles (parent, className, newFile);
});
return;
}
safeThis->createNewFileInternal (parent);
};
asyncAlertWindow->enterModalState (true, ModalCallbackFunction::create (std::move (resultCallback)), false);
}
std::unique_ptr<AlertWindow> asyncAlertWindow;
JUCE_DECLARE_WEAK_REFERENCEABLE (NewComponentFileWizard)
};
//==============================================================================
class NewSingleFileComponentFileWizard : public NewComponentFileWizard
{
public:
String getName() override { return "Component class (in a single source file)"; }
void createFiles (Project::Item parent, const String& className, const File& newFile) override
{
create (className, parent, newFile.withFileExtension ("h"), "jucer_NewInlineComponentTemplate_h");
}
};
//==============================================================================
void NewFileWizard::Type::showFailedToWriteMessage (const File& file)
{
AlertWindow::showMessageBoxAsync (MessageBoxIconType::WarningIcon,
"Failed to Create File!",
"Couldn't write to the file: " + file.getFullPathName());
}
void NewFileWizard::Type::askUserToChooseNewFile (const String& suggestedFilename, const String& wildcard,
const Project::Item& projectGroupToAddTo,
std::function<void (File)> callback)
{
chooser = std::make_unique<FileChooser> ("Select File to Create",
projectGroupToAddTo.determineGroupFolder()
.getChildFile (suggestedFilename)
.getNonexistentSibling(),
wildcard);
auto flags = FileBrowserComponent::saveMode
| FileBrowserComponent::canSelectFiles
| FileBrowserComponent::warnAboutOverwriting;
chooser->launchAsync (flags, [callback] (const FileChooser& fc)
{
callback (fc.getResult());
});
}
//==============================================================================
NewFileWizard::NewFileWizard()
{
registerWizard (new NewCppFileWizard());
registerWizard (new NewHeaderFileWizard());
registerWizard (new NewCppAndHeaderFileWizard());
registerWizard (new NewComponentFileWizard());
registerWizard (new NewSingleFileComponentFileWizard());
}
NewFileWizard::~NewFileWizard()
{
}
void NewFileWizard::addWizardsToMenu (PopupMenu& m) const
{
for (int i = 0; i < wizards.size(); ++i)
m.addItem (menuBaseID + i, "Add New " + wizards.getUnchecked(i)->getName() + "...");
}
bool NewFileWizard::runWizardFromMenu (int chosenMenuItemID, Project& project, const Project::Item& projectGroupToAddTo) const
{
if (Type* wiz = wizards [chosenMenuItemID - menuBaseID])
{
wiz->createNewFile (project, projectGroupToAddTo);
return true;
}
return false;
}
void NewFileWizard::registerWizard (Type* newWizard)
{
wizards.add (newWizard);
}

View File

@ -0,0 +1,70 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../../Project/jucer_Project.h"
//==============================================================================
class NewFileWizard
{
public:
//==============================================================================
NewFileWizard();
~NewFileWizard();
//==============================================================================
class Type
{
public:
Type() {}
virtual ~Type() {}
//==============================================================================
virtual String getName() = 0;
virtual void createNewFile (Project&, Project::Item projectGroupToAddTo) = 0;
protected:
//==============================================================================
void askUserToChooseNewFile (const String& suggestedFilename, const String& wildcard,
const Project::Item& projectGroupToAddTo,
std::function<void (File)> callback);
static void showFailedToWriteMessage (const File& file);
private:
std::unique_ptr<FileChooser> chooser;
};
//==============================================================================
void addWizardsToMenu (PopupMenu&) const;
bool runWizardFromMenu (int chosenMenuItemID, Project&,
const Project::Item& projectGroupToAddTo) const;
void registerWizard (Type*);
private:
OwnedArray<Type> wizards;
};

View File

@ -0,0 +1,393 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
// Handy list of static Identifiers..
namespace Ids
{
#define DECLARE_ID(name) const Identifier name (#name)
DECLARE_ID (name);
DECLARE_ID (file);
DECLARE_ID (path);
DECLARE_ID (text);
DECLARE_ID (vendor);
DECLARE_ID (version);
DECLARE_ID (license);
DECLARE_ID (minimumCppStandard);
DECLARE_ID (include);
DECLARE_ID (info);
DECLARE_ID (description);
DECLARE_ID (companyName);
DECLARE_ID (companyCopyright);
DECLARE_ID (companyWebsite);
DECLARE_ID (companyEmail);
DECLARE_ID (useAppConfig);
DECLARE_ID (addUsingNamespaceToJuceHeader);
DECLARE_ID (usePrecompiledHeaderFile);
DECLARE_ID (precompiledHeaderFile);
DECLARE_ID (displaySplashScreen);
DECLARE_ID (splashScreenColour);
DECLARE_ID (position);
DECLARE_ID (source);
DECLARE_ID (width);
DECLARE_ID (height);
DECLARE_ID (bounds);
DECLARE_ID (background);
DECLARE_ID (initialState);
DECLARE_ID (targetFolder);
DECLARE_ID (intermediatesPath);
DECLARE_ID (modulePaths);
DECLARE_ID (searchpaths);
DECLARE_ID (osxFallback);
DECLARE_ID (windowsFallback);
DECLARE_ID (linuxFallback);
DECLARE_ID (jucePath);
DECLARE_ID (defaultJuceModulePath);
DECLARE_ID (defaultUserModulePath);
DECLARE_ID (vstLegacyFolder);
DECLARE_ID (vst3Folder);
DECLARE_ID (rtasFolder);
DECLARE_ID (auFolder);
DECLARE_ID (vstLegacyPath);
DECLARE_ID (rtasPath);
DECLARE_ID (aaxPath);
DECLARE_ID (flags);
DECLARE_ID (line);
DECLARE_ID (index);
DECLARE_ID (type);
DECLARE_ID (time);
DECLARE_ID (extraCompilerFlags);
DECLARE_ID (extraLinkerFlags);
DECLARE_ID (externalLibraries);
DECLARE_ID (extraDefs);
DECLARE_ID (projectType);
DECLARE_ID (isDebug);
DECLARE_ID (alwaysGenerateDebugSymbols);
DECLARE_ID (targetName);
DECLARE_ID (binaryPath);
DECLARE_ID (recommendedWarnings);
DECLARE_ID (optimisation);
DECLARE_ID (defines);
DECLARE_ID (headerPath);
DECLARE_ID (systemHeaderPath);
DECLARE_ID (liveWindowsTargetPlatformVersion);
DECLARE_ID (libraryPath);
DECLARE_ID (customXcodeFlags);
DECLARE_ID (customXcassetsFolder);
DECLARE_ID (customLaunchStoryboard);
DECLARE_ID (customXcodeResourceFolders);
DECLARE_ID (plistPreprocessorDefinitions);
DECLARE_ID (applicationCategory);
DECLARE_ID (customPList);
DECLARE_ID (pListPrefixHeader);
DECLARE_ID (pListPreprocess);
DECLARE_ID (UIFileSharingEnabled);
DECLARE_ID (UISupportsDocumentBrowser);
DECLARE_ID (UIStatusBarHidden);
DECLARE_ID (UIRequiresFullScreen);
DECLARE_ID (documentExtensions);
DECLARE_ID (keepCustomXcodeSchemes);
DECLARE_ID (useHeaderMap);
DECLARE_ID (cppLanguageStandard);
DECLARE_ID (enableGNUExtensions);
DECLARE_ID (cppLibType);
DECLARE_ID (codeSigningIdentity);
DECLARE_ID (fastMath);
DECLARE_ID (linkTimeOptimisation);
DECLARE_ID (vstBinaryLocation);
DECLARE_ID (vst3BinaryLocation);
DECLARE_ID (auBinaryLocation);
DECLARE_ID (rtasBinaryLocation);
DECLARE_ID (aaxBinaryLocation);
DECLARE_ID (unityPluginBinaryLocation);
DECLARE_ID (enablePluginBinaryCopyStep);
DECLARE_ID (stripLocalSymbols);
DECLARE_ID (macOSBaseSDK);
DECLARE_ID (macOSDeploymentTarget);
DECLARE_ID (osxArchitecture);
DECLARE_ID (iosBaseSDK);
DECLARE_ID (iosDeploymentTarget);
DECLARE_ID (xcodeSubprojects);
DECLARE_ID (extraFrameworks);
DECLARE_ID (frameworkSearchPaths);
DECLARE_ID (extraCustomFrameworks);
DECLARE_ID (embeddedFrameworks);
DECLARE_ID (extraDLLs);
DECLARE_ID (winArchitecture);
DECLARE_ID (winWarningLevel);
DECLARE_ID (msvcManifestFile);
DECLARE_ID (warningsAreErrors);
DECLARE_ID (linuxArchitecture);
DECLARE_ID (linuxCodeBlocksArchitecture);
DECLARE_ID (windowsCodeBlocksArchitecture);
DECLARE_ID (codeBlocksWindowsTarget);
DECLARE_ID (toolset);
DECLARE_ID (windowsTargetPlatformVersion);
DECLARE_ID (debugInformationFormat);
DECLARE_ID (IPPLibrary);
DECLARE_ID (IPP1ALibrary);
DECLARE_ID (MKL1ALibrary);
DECLARE_ID (msvcModuleDefinitionFile);
DECLARE_ID (bigIcon);
DECLARE_ID (smallIcon);
DECLARE_ID (prebuildCommand);
DECLARE_ID (postbuildCommand);
DECLARE_ID (generateManifest);
DECLARE_ID (useRuntimeLibDLL);
DECLARE_ID (multiProcessorCompilation);
DECLARE_ID (enableIncrementalLinking);
DECLARE_ID (bundleIdentifier);
DECLARE_ID (aaxIdentifier);
DECLARE_ID (aaxFolder);
DECLARE_ID (compile);
DECLARE_ID (noWarnings);
DECLARE_ID (skipPCH);
DECLARE_ID (resource);
DECLARE_ID (xcodeResource);
DECLARE_ID (xcodeValidArchs);
DECLARE_ID (className);
DECLARE_ID (classDesc);
DECLARE_ID (controlPoint);
DECLARE_ID (createCallback);
DECLARE_ID (parentClasses);
DECLARE_ID (constructorParams);
DECLARE_ID (objectConstructionArgs);
DECLARE_ID (memberInitialisers);
DECLARE_ID (canBeAggregated);
DECLARE_ID (rootItemVisible);
DECLARE_ID (openByDefault);
DECLARE_ID (locked);
DECLARE_ID (tooltip);
DECLARE_ID (memberName);
DECLARE_ID (markerName);
DECLARE_ID (focusOrder);
DECLARE_ID (hidden);
DECLARE_ID (useStdCall);
DECLARE_ID (useGlobalPath);
DECLARE_ID (showAllCode);
DECLARE_ID (useLocalCopy);
DECLARE_ID (overwriteOnSave);
DECLARE_ID (appSandbox);
DECLARE_ID (appSandboxInheritance);
DECLARE_ID (appSandboxOptions);
DECLARE_ID (hardenedRuntime);
DECLARE_ID (hardenedRuntimeOptions);
DECLARE_ID (microphonePermissionNeeded);
DECLARE_ID (microphonePermissionsText);
DECLARE_ID (cameraPermissionNeeded);
DECLARE_ID (cameraPermissionText);
DECLARE_ID (sendAppleEventsPermissionNeeded);
DECLARE_ID (sendAppleEventsPermissionText);
DECLARE_ID (androidJavaLibs);
DECLARE_ID (androidAdditionalJavaFolders);
DECLARE_ID (androidAdditionalResourceFolders);
DECLARE_ID (androidProjectRepositories);
DECLARE_ID (androidRepositories);
DECLARE_ID (androidDependencies);
DECLARE_ID (androidCustomAppBuildGradleContent);
DECLARE_ID (androidBuildConfigRemoteNotifsConfigFile);
DECLARE_ID (androidAdditionalXmlValueResources);
DECLARE_ID (androidAdditionalDrawableResources);
DECLARE_ID (androidAdditionalRawValueResources);
// DECLARE_ID (androidActivityClass); // DEPRECATED!
const Identifier androidCustomActivityClass ("androidActivitySubClassName"); // old name is very confusing, but we need to remain backward compatible
// DECLARE_ID (androidActivityBaseClassName); // DEPRECATED!
DECLARE_ID (androidCustomApplicationClass);
DECLARE_ID (androidVersionCode);
DECLARE_ID (androidSDKPath);
DECLARE_ID (androidOboeRepositoryPath);
DECLARE_ID (androidInternetNeeded);
DECLARE_ID (androidArchitectures);
DECLARE_ID (androidManifestCustomXmlElements);
DECLARE_ID (androidGradleSettingsContent);
DECLARE_ID (androidCustomStringXmlElements);
DECLARE_ID (androidBluetoothNeeded);
DECLARE_ID (androidExternalReadNeeded);
DECLARE_ID (androidExternalWriteNeeded);
DECLARE_ID (androidInAppBilling);
DECLARE_ID (androidVibratePermissionNeeded);
DECLARE_ID (androidPushNotifications);
DECLARE_ID (androidEnableRemoteNotifications);
DECLARE_ID (androidRemoteNotificationsConfigFile);
DECLARE_ID (androidEnableContentSharing);
DECLARE_ID (androidMinimumSDK);
DECLARE_ID (androidTargetSDK);
DECLARE_ID (androidOtherPermissions);
DECLARE_ID (androidKeyStore);
DECLARE_ID (androidKeyStorePass);
DECLARE_ID (androidKeyAlias);
DECLARE_ID (androidKeyAliasPass);
DECLARE_ID (androidTheme);
DECLARE_ID (androidStaticLibraries);
DECLARE_ID (androidSharedLibraries);
DECLARE_ID (androidScreenOrientation);
DECLARE_ID (androidExtraAssetsFolder);
DECLARE_ID (androidStudioExePath);
DECLARE_ID (iosDeviceFamily);
const Identifier iPhoneScreenOrientation ("iosScreenOrientation"); // old name is confusing
DECLARE_ID (iPadScreenOrientation);
DECLARE_ID (iosScreenOrientation);
DECLARE_ID (iosInAppPurchases);
DECLARE_ID (iosContentSharing);
DECLARE_ID (iosBackgroundAudio);
DECLARE_ID (iosBackgroundBle);
DECLARE_ID (iosPushNotifications);
DECLARE_ID (iosAppGroups);
DECLARE_ID (iCloudPermissions);
DECLARE_ID (networkingMulticast);
DECLARE_ID (iosDevelopmentTeamID);
DECLARE_ID (iosAppGroupsId);
DECLARE_ID (iosBluetoothPermissionNeeded);
DECLARE_ID (iosBluetoothPermissionText);
DECLARE_ID (duplicateAppExResourcesFolder);
DECLARE_ID (buildToolsVersion);
DECLARE_ID (gradleVersion);
const Identifier androidPluginVersion ("gradleWrapperVersion"); // old name is very confusing, but we need to remain backward compatible
DECLARE_ID (gradleToolchain);
DECLARE_ID (gradleToolchainVersion);
DECLARE_ID (linuxExtraPkgConfig);
DECLARE_ID (clionMakefileEnabled);
DECLARE_ID (clionXcodeEnabled);
DECLARE_ID (clionCodeBlocksEnabled);
DECLARE_ID (clionExePath);
DECLARE_ID (font);
DECLARE_ID (colour);
DECLARE_ID (userNotes);
DECLARE_ID (maxBinaryFileSize);
DECLARE_ID (includeBinaryInJuceHeader);
DECLARE_ID (binaryDataNamespace);
DECLARE_ID (characterSet);
DECLARE_ID (JUCERPROJECT);
DECLARE_ID (MAINGROUP);
DECLARE_ID (EXPORTFORMATS);
DECLARE_ID (GROUP);
DECLARE_ID (FILE);
DECLARE_ID (MODULES);
DECLARE_ID (MODULE);
DECLARE_ID (JUCEOPTIONS);
DECLARE_ID (CONFIGURATIONS);
DECLARE_ID (CONFIGURATION);
DECLARE_ID (MODULEPATHS);
DECLARE_ID (MODULEPATH);
DECLARE_ID (PATH);
DECLARE_ID (userpath);
DECLARE_ID (systempath);
DECLARE_ID (utilsCppInclude);
DECLARE_ID (juceModulesFolder);
DECLARE_ID (parentActive);
DECLARE_ID (message);
DECLARE_ID (start);
DECLARE_ID (end);
DECLARE_ID (range);
DECLARE_ID (location);
DECLARE_ID (key);
DECLARE_ID (list);
DECLARE_ID (METADATA);
DECLARE_ID (DEPENDENCIES);
DECLARE_ID (CLASSLIST);
DECLARE_ID (CLASS);
DECLARE_ID (MEMBER);
DECLARE_ID (METHOD);
DECLARE_ID (LITERALS);
DECLARE_ID (LITERAL);
DECLARE_ID (abstract);
DECLARE_ID (anonymous);
DECLARE_ID (noDefConstructor);
DECLARE_ID (returnType);
DECLARE_ID (numArgs);
DECLARE_ID (declaration);
DECLARE_ID (definition);
DECLARE_ID (classDecl);
DECLARE_ID (initialisers);
DECLARE_ID (destructors);
DECLARE_ID (pluginFormats);
DECLARE_ID (buildVST);
DECLARE_ID (buildVST3);
DECLARE_ID (buildAU);
DECLARE_ID (buildAUv3);
DECLARE_ID (buildRTAS);
DECLARE_ID (buildAAX);
DECLARE_ID (buildStandalone);
DECLARE_ID (buildUnity);
DECLARE_ID (enableIAA);
DECLARE_ID (pluginName);
DECLARE_ID (pluginDesc);
DECLARE_ID (pluginManufacturer);
DECLARE_ID (pluginManufacturerCode);
DECLARE_ID (pluginCode);
DECLARE_ID (pluginChannelConfigs);
DECLARE_ID (pluginCharacteristicsValue);
DECLARE_ID (pluginCharacteristics);
DECLARE_ID (extraPluginFormats);
DECLARE_ID (pluginIsSynth);
DECLARE_ID (pluginWantsMidiIn);
DECLARE_ID (pluginProducesMidiOut);
DECLARE_ID (pluginIsMidiEffectPlugin);
DECLARE_ID (pluginEditorRequiresKeys);
DECLARE_ID (pluginVSTCategory);
DECLARE_ID (pluginVST3Category);
DECLARE_ID (pluginAUExportPrefix);
DECLARE_ID (pluginAUMainType);
DECLARE_ID (pluginAUIsSandboxSafe);
DECLARE_ID (pluginRTASCategory);
DECLARE_ID (pluginRTASDisableBypass);
DECLARE_ID (pluginRTASDisableMultiMono);
DECLARE_ID (pluginAAXCategory);
DECLARE_ID (pluginAAXDisableBypass);
DECLARE_ID (pluginAAXDisableMultiMono);
DECLARE_ID (pluginVSTNumMidiInputs);
DECLARE_ID (pluginVSTNumMidiOutputs);
DECLARE_ID (suppressPlistResourceUsage);
DECLARE_ID (useLegacyBuildSystem);
DECLARE_ID (exporters);
DECLARE_ID (website);
DECLARE_ID (mainClass);
DECLARE_ID (moduleFlags);
DECLARE_ID (projectLineFeed);
DECLARE_ID (compilerFlagSchemes);
DECLARE_ID (compilerFlagScheme);
DECLARE_ID (dontQueryForUpdate);
DECLARE_ID (dontAskAboutJUCEPath);
DECLARE_ID (postExportShellCommandPosix);
DECLARE_ID (postExportShellCommandWin);
DECLARE_ID (guiEditorEnabled);
DECLARE_ID (jucerFormatVersion);
DECLARE_ID (buildNumber);
DECLARE_ID (osxSDK);
DECLARE_ID (osxCompatibility);
DECLARE_ID (iosCompatibility);
const Identifier ID ("id");
const Identifier ID_uppercase ("ID");
const Identifier class_ ("class");
const Identifier dependencies_ ("dependencies");
#undef DECLARE_ID
}

View File

@ -0,0 +1,326 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
struct TranslationHelpers
{
static void addString (StringArray& strings, const String& s)
{
if (s.isNotEmpty() && ! strings.contains (s))
strings.add (s);
}
static void scanFileForTranslations (StringArray& strings, const File& file)
{
auto content = file.loadFileAsString();
auto p = content.getCharPointer();
for (;;)
{
p = CharacterFunctions::find (p, CharPointer_ASCII ("TRANS"));
if (p.isEmpty())
break;
p += 5;
p.incrementToEndOfWhitespace();
if (*p == '(')
{
++p;
MemoryOutputStream text;
parseStringLiteral (p, text);
addString (strings, text.toString());
}
}
}
static void parseStringLiteral (String::CharPointerType& p, MemoryOutputStream& out) noexcept
{
p.incrementToEndOfWhitespace();
if (p.getAndAdvance() == '"')
{
auto start = p;
for (;;)
{
auto c = *p;
if (c == '"')
{
out << String (start, p);
++p;
parseStringLiteral (p, out);
return;
}
if (c == 0)
break;
if (c == '\\')
{
out << String (start, p);
++p;
out << String::charToString (readEscapedChar (p));
start = p + 1;
}
++p;
}
}
}
static juce_wchar readEscapedChar (String::CharPointerType& p)
{
auto c = *p;
switch (c)
{
case '"':
case '\\':
case '/': break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'x':
++p;
c = 0;
for (int i = 4; --i >= 0;)
{
const int digitValue = CharacterFunctions::getHexDigitValue (*p);
if (digitValue < 0)
break;
++p;
c = (c << 4) + (juce_wchar) digitValue;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
c = 0;
for (int i = 4; --i >= 0;)
{
const auto digitValue = (int) (*p - '0');
if (digitValue < 0 || digitValue > 7)
break;
++p;
c = (c << 3) + (juce_wchar) digitValue;
}
break;
default:
break;
}
return c;
}
static void scanFilesForTranslations (StringArray& strings, const Project::Item& p)
{
if (p.isFile())
{
const File file (p.getFile());
if (file.hasFileExtension (sourceOrHeaderFileExtensions))
scanFileForTranslations (strings, file);
}
for (int i = 0; i < p.getNumChildren(); ++i)
scanFilesForTranslations (strings, p.getChild (i));
}
static void scanFolderForTranslations (StringArray& strings, const File& root)
{
for (const auto& i : RangedDirectoryIterator (root, true))
{
const auto file = i.getFile();
if (file.hasFileExtension (sourceOrHeaderFileExtensions))
scanFileForTranslations(strings, file);
}
}
static void scanProject (StringArray& strings, Project& project)
{
scanFilesForTranslations (strings, project.getMainGroup());
OwnedArray<LibraryModule> modules;
project.getEnabledModules().createRequiredModules (modules);
for (int j = 0; j < modules.size(); ++j)
{
const File localFolder (modules.getUnchecked(j)->getFolder());
Array<File> files;
modules.getUnchecked(j)->findBrowseableFiles (localFolder, files);
for (int i = 0; i < files.size(); ++i)
scanFileForTranslations (strings, files.getReference(i));
}
}
static const char* getMungingSeparator() { return "JCTRIDX"; }
static StringArray breakApart (const String& munged)
{
StringArray lines, result;
lines.addLines (munged);
String currentItem;
for (int i = 0; i < lines.size(); ++i)
{
if (lines[i].contains (getMungingSeparator()))
{
if (currentItem.isNotEmpty())
result.add (currentItem);
currentItem = String();
}
else
{
if (currentItem.isNotEmpty())
currentItem << newLine;
currentItem << lines[i];
}
}
if (currentItem.isNotEmpty())
result.add (currentItem);
return result;
}
static StringArray withTrimmedEnds (StringArray array)
{
for (auto& s : array)
s = s.trimEnd().removeCharacters ("\r\n");
return array;
}
static String escapeString (const String& s)
{
return s.replace ("\"", "\\\"")
.replace ("\'", "\\\'")
.replace ("\t", "\\t")
.replace ("\r", "\\r")
.replace ("\n", "\\n");
}
static String getPreTranslationText (Project& project)
{
StringArray strings;
scanProject (strings, project);
return mungeStrings (strings);
}
static String getPreTranslationText (const LocalisedStrings& strings)
{
return mungeStrings (strings.getMappings().getAllKeys());
}
static String mungeStrings (const StringArray& strings)
{
MemoryOutputStream s;
for (int i = 0; i < strings.size(); ++i)
{
s << getMungingSeparator() << i << "." << newLine << strings[i];
if (i < strings.size() - 1)
s << newLine;
}
return s.toString();
}
static String createLine (const String& preString, const String& postString)
{
return "\"" + escapeString (preString)
+ "\" = \""
+ escapeString (postString) + "\"";
}
static String createFinishedTranslationFile (StringArray preStrings,
StringArray postStrings,
const LocalisedStrings& original)
{
const StringPairArray& originalStrings (original.getMappings());
StringArray lines;
if (originalStrings.size() > 0)
{
lines.add ("language: " + original.getLanguageName());
lines.add ("countries: " + original.getCountryCodes().joinIntoString (" "));
lines.add (String());
const StringArray& originalKeys (originalStrings.getAllKeys());
const StringArray& originalValues (originalStrings.getAllValues());
int numRemoved = 0;
for (int i = preStrings.size(); --i >= 0;)
{
if (originalKeys.contains (preStrings[i]))
{
preStrings.remove (i);
postStrings.remove (i);
++numRemoved;
}
}
for (int i = 0; i < originalStrings.size(); ++i)
lines.add (createLine (originalKeys[i], originalValues[i]));
}
else
{
lines.add ("language: [enter full name of the language here!]");
lines.add ("countries: [enter list of 2-character country codes here!]");
lines.add (String());
}
for (int i = 0; i < preStrings.size(); ++i)
lines.add (createLine (preStrings[i], postStrings[i]));
return lines.joinIntoString (newLine);
}
};

View File

@ -0,0 +1,50 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
template <typename Type>
class NumericValueSource : public ValueSourceFilter
{
public:
NumericValueSource (const Value& source) : ValueSourceFilter (source) {}
var getValue() const override
{
return (Type) sourceValue.getValue();
}
void setValue (const var& newValue) override
{
const Type newVal = static_cast<Type> (newValue);
if (newVal != static_cast<Type> (getValue())) // this test is important, because if a property is missing, it won't
sourceValue = newVal; // create it (causing an unwanted undo action) when a control sets it to 0
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (NumericValueSource)
};

View File

@ -0,0 +1,73 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
/**
Wraps a ValueWithDefault object that has a default which depends on a global value.
*/
class ValueWithDefaultWrapper : private Value::Listener
{
public:
ValueWithDefaultWrapper() = default;
void init (const ValueWithDefault& vwd, ValueWithDefault global, TargetOS::OS targetOS)
{
wrappedValue = vwd;
globalValue = global.getPropertyAsValue();
globalIdentifier = global.getPropertyID();
os = targetOS;
if (wrappedValue.get() == var())
wrappedValue.resetToDefault();
globalValue.addListener (this);
valueChanged (globalValue);
}
ValueWithDefault& getWrappedValueWithDefault()
{
return wrappedValue;
}
var getCurrentValue() const
{
return wrappedValue.get();
}
private:
void valueChanged (Value&) override
{
wrappedValue.setDefault (getAppSettings().getStoredPath (globalIdentifier, os).get());
}
ValueWithDefault wrappedValue;
Value globalValue;
Identifier globalIdentifier;
TargetOS::OS os;
};

View File

@ -0,0 +1,126 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_VersionInfo.h"
VersionInfo::VersionInfo (String versionIn, String releaseNotesIn, std::vector<Asset> assetsIn)
: versionString (std::move (versionIn)),
releaseNotes (std::move (releaseNotesIn)),
assets (std::move (assetsIn))
{}
std::unique_ptr<VersionInfo> VersionInfo::fetchFromUpdateServer (const String& versionString)
{
return fetch ("tags/" + versionString);
}
std::unique_ptr<VersionInfo> VersionInfo::fetchLatestFromUpdateServer()
{
return fetch ("latest");
}
std::unique_ptr<InputStream> VersionInfo::createInputStreamForAsset (const Asset& asset, int& statusCode)
{
URL downloadUrl (asset.url);
StringPairArray responseHeaders;
return std::unique_ptr<InputStream> (downloadUrl.createInputStream (URL::InputStreamOptions (URL::ParameterHandling::inAddress)
.withExtraHeaders ("Accept: application/octet-stream")
.withConnectionTimeoutMs (5000)
.withResponseHeaders (&responseHeaders)
.withStatusCode (&statusCode)
.withNumRedirectsToFollow (1)));
}
bool VersionInfo::isNewerVersionThanCurrent()
{
jassert (versionString.isNotEmpty());
auto currentTokens = StringArray::fromTokens (ProjectInfo::versionString, ".", {});
auto thisTokens = StringArray::fromTokens (versionString, ".", {});
jassert (thisTokens.size() == 3);
if (currentTokens[0].getIntValue() == thisTokens[0].getIntValue())
{
if (currentTokens[1].getIntValue() == thisTokens[1].getIntValue())
return currentTokens[2].getIntValue() < thisTokens[2].getIntValue();
return currentTokens[1].getIntValue() < thisTokens[1].getIntValue();
}
return currentTokens[0].getIntValue() < thisTokens[0].getIntValue();
}
std::unique_ptr<VersionInfo> VersionInfo::fetch (const String& endpoint)
{
URL latestVersionURL ("https://api.github.com/repos/juce-framework/JUCE/releases/" + endpoint);
std::unique_ptr<InputStream> inStream (latestVersionURL.createInputStream (URL::InputStreamOptions (URL::ParameterHandling::inAddress)
.withConnectionTimeoutMs (5000)));
if (inStream == nullptr)
return nullptr;
auto content = inStream->readEntireStreamAsString();
auto latestReleaseDetails = JSON::parse (content);
auto* json = latestReleaseDetails.getDynamicObject();
if (json == nullptr)
return nullptr;
auto versionString = json->getProperty ("tag_name").toString();
if (versionString.isEmpty())
return nullptr;
auto* assets = json->getProperty ("assets").getArray();
if (assets == nullptr)
return nullptr;
auto releaseNotes = json->getProperty ("body").toString();
std::vector<VersionInfo::Asset> parsedAssets;
for (auto& asset : *assets)
{
if (auto* assetJson = asset.getDynamicObject())
{
parsedAssets.push_back ({ assetJson->getProperty ("name").toString(),
assetJson->getProperty ("url").toString() });
jassert (parsedAssets.back().name.isNotEmpty());
jassert (parsedAssets.back().url.isNotEmpty());
}
else
{
jassertfalse;
}
}
return std::unique_ptr<VersionInfo> (new VersionInfo { versionString, releaseNotes, std::move (parsedAssets) });
}

View File

@ -0,0 +1,53 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
class VersionInfo
{
public:
struct Asset
{
const String name;
const String url;
};
static std::unique_ptr<VersionInfo> fetchFromUpdateServer (const String& versionString);
static std::unique_ptr<VersionInfo> fetchLatestFromUpdateServer();
static std::unique_ptr<InputStream> createInputStreamForAsset (const Asset& asset, int& statusCode);
bool isNewerVersionThanCurrent();
const String versionString;
const String releaseNotes;
const std::vector<Asset> assets;
private:
VersionInfo (String version, String releaseNotes, std::vector<Asset> assets);
static std::unique_ptr<VersionInfo> fetch (const String&);
};

View File

@ -0,0 +1,559 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "../../ProjectSaving/jucer_ProjectExporter.h"
#include "../../ProjectSaving/jucer_ProjectExport_Xcode.h"
#include "../../ProjectSaving/jucer_ProjectExport_Android.h"
#include "jucer_PIPGenerator.h"
//==============================================================================
static void ensureSingleNewLineAfterIncludes (StringArray& lines)
{
int lastIncludeIndex = -1;
for (int i = 0; i < lines.size(); ++i)
{
if (lines[i].contains ("#include"))
lastIncludeIndex = i;
}
if (lastIncludeIndex != -1)
{
auto index = lastIncludeIndex;
int numNewLines = 0;
while (++index < lines.size() && lines[index].isEmpty())
++numNewLines;
if (numNewLines > 1)
lines.removeRange (lastIncludeIndex + 1, numNewLines - 1);
}
}
static String ensureCorrectWhitespace (StringRef input)
{
auto lines = StringArray::fromLines (input);
ensureSingleNewLineAfterIncludes (lines);
return joinLinesIntoSourceFile (lines);
}
static bool isJUCEExample (const File& pipFile)
{
int numLinesToTest = 10; // license should be at the top of the file so no need to
// check all lines
for (auto line : StringArray::fromLines (pipFile.loadFileAsString()))
{
if (line.contains ("This file is part of the JUCE examples."))
return true;
--numLinesToTest;
}
return false;
}
static bool isValidExporterIdentifier (const Identifier& exporterIdentifier)
{
return ProjectExporter::getTypeInfoForExporter (exporterIdentifier).identifier.toString().isNotEmpty();
}
static bool exporterRequiresExampleAssets (const Identifier& exporterIdentifier, const String& projectName)
{
return (exporterIdentifier.toString() == XcodeProjectExporter::getValueTreeTypeNameiOS()
|| exporterIdentifier.toString() == AndroidProjectExporter::getValueTreeTypeName())
|| (exporterIdentifier.toString() == XcodeProjectExporter::getValueTreeTypeNameMac() && projectName == "AUv3SynthPlugin");
}
//==============================================================================
PIPGenerator::PIPGenerator (const File& pip, const File& output, const File& jucePath, const File& userPath)
: pipFile (pip),
juceModulesPath (jucePath),
userModulesPath (userPath),
metadata (parseJUCEHeaderMetadata (pipFile))
{
if (output != File())
{
outputDirectory = output;
isTemp = false;
}
else
{
outputDirectory = File::getSpecialLocation (File::SpecialLocationType::tempDirectory).getChildFile ("PIPs");
isTemp = true;
}
auto isClipboard = (pip.getParentDirectory().getFileName() == "Clipboard"
&& pip.getParentDirectory().getParentDirectory().getFileName() == "PIPs");
outputDirectory = outputDirectory.getChildFile (metadata[Ids::name].toString()).getNonexistentSibling();
useLocalCopy = metadata[Ids::useLocalCopy].toString().trim().getIntValue() == 1 || isClipboard;
if (userModulesPath != File())
{
availableUserModules.reset (new AvailableModulesList());
availableUserModules->scanPaths ({ userModulesPath });
}
}
//==============================================================================
Result PIPGenerator::createJucerFile()
{
ValueTree root (Ids::JUCERPROJECT);
auto result = setProjectSettings (root);
if (result != Result::ok())
return result;
addModules (root);
addExporters (root);
createFiles (root);
setModuleFlags (root);
auto outputFile = outputDirectory.getChildFile (metadata[Ids::name].toString() + ".jucer");
if (auto xml = root.createXml())
if (xml->writeTo (outputFile, {}))
return Result::ok();
return Result::fail ("Failed to create .jucer file in " + outputDirectory.getFullPathName());
}
Result PIPGenerator::createMainCpp()
{
auto outputFile = outputDirectory.getChildFile ("Source").getChildFile ("Main.cpp");
if (! outputFile.existsAsFile() && (outputFile.create() != Result::ok()))
return Result::fail ("Failed to create Main.cpp - " + outputFile.getFullPathName());
outputFile.replaceWithText (getMainFileTextForType());
return Result::ok();
}
//==============================================================================
void PIPGenerator::addFileToTree (ValueTree& groupTree, const String& name, bool compile, const String& path)
{
ValueTree file (Ids::FILE);
file.setProperty (Ids::ID, createAlphaNumericUID(), nullptr);
file.setProperty (Ids::name, name, nullptr);
file.setProperty (Ids::compile, compile, nullptr);
file.setProperty (Ids::resource, 0, nullptr);
file.setProperty (Ids::file, path, nullptr);
groupTree.addChild (file, -1, nullptr);
}
void PIPGenerator::createFiles (ValueTree& jucerTree)
{
auto sourceDir = outputDirectory.getChildFile ("Source");
if (! sourceDir.exists())
sourceDir.createDirectory();
if (useLocalCopy)
pipFile.copyFileTo (sourceDir.getChildFile (pipFile.getFileName()));
ValueTree mainGroup (Ids::MAINGROUP);
mainGroup.setProperty (Ids::ID, createAlphaNumericUID(), nullptr);
mainGroup.setProperty (Ids::name, metadata[Ids::name], nullptr);
ValueTree group (Ids::GROUP);
group.setProperty (Ids::ID, createGUID (sourceDir.getFullPathName() + "_guidpathsaltxhsdf"), nullptr);
group.setProperty (Ids::name, "Source", nullptr);
addFileToTree (group, "Main.cpp", true, "Source/Main.cpp");
addFileToTree (group, pipFile.getFileName(), false, useLocalCopy ? "Source/" + pipFile.getFileName()
: pipFile.getFullPathName());
mainGroup.addChild (group, -1, nullptr);
if (useLocalCopy)
{
auto relativeFiles = replaceRelativeIncludesAndGetFilesToMove();
if (relativeFiles.size() > 0)
{
ValueTree assets (Ids::GROUP);
assets.setProperty (Ids::ID, createAlphaNumericUID(), nullptr);
assets.setProperty (Ids::name, "Assets", nullptr);
for (auto& f : relativeFiles)
if (copyRelativeFileToLocalSourceDirectory (f))
addFileToTree (assets, f.getFileName(), f.getFileExtension() == ".cpp", "Source/" + f.getFileName());
mainGroup.addChild (assets, -1, nullptr);
}
}
jucerTree.addChild (mainGroup, 0, nullptr);
}
ValueTree PIPGenerator::createModulePathChild (const String& moduleID)
{
ValueTree modulePath (Ids::MODULEPATH);
modulePath.setProperty (Ids::ID, moduleID, nullptr);
modulePath.setProperty (Ids::path, getPathForModule (moduleID), nullptr);
return modulePath;
}
ValueTree PIPGenerator::createBuildConfigChild (bool isDebug)
{
ValueTree child (Ids::CONFIGURATION);
child.setProperty (Ids::name, isDebug ? "Debug" : "Release", nullptr);
child.setProperty (Ids::isDebug, isDebug ? 1 : 0, nullptr);
child.setProperty (Ids::optimisation, isDebug ? 1 : 3, nullptr);
child.setProperty (Ids::targetName, metadata[Ids::name], nullptr);
return child;
}
ValueTree PIPGenerator::createExporterChild (const Identifier& exporterIdentifier)
{
ValueTree exporter (exporterIdentifier);
exporter.setProperty (Ids::targetFolder, "Builds/" + ProjectExporter::getTypeInfoForExporter (exporterIdentifier).targetFolder, nullptr);
if (isJUCEExample (pipFile) && exporterRequiresExampleAssets (exporterIdentifier, metadata[Ids::name]))
{
auto examplesDir = getExamplesDirectory();
if (examplesDir != File())
{
auto assetsDirectoryPath = examplesDir.getChildFile ("Assets").getFullPathName();
exporter.setProperty (exporterIdentifier.toString() == AndroidProjectExporter::getValueTreeTypeName() ? Ids::androidExtraAssetsFolder
: Ids::customXcodeResourceFolders,
assetsDirectoryPath, nullptr);
}
else
{
// invalid JUCE path
jassertfalse;
}
}
{
ValueTree configs (Ids::CONFIGURATIONS);
configs.addChild (createBuildConfigChild (true), -1, nullptr);
configs.addChild (createBuildConfigChild (false), -1, nullptr);
exporter.addChild (configs, -1, nullptr);
}
{
ValueTree modulePaths (Ids::MODULEPATHS);
auto modules = StringArray::fromTokens (metadata[Ids::dependencies_].toString(), ",", {});
for (auto m : modules)
modulePaths.addChild (createModulePathChild (m.trim()), -1, nullptr);
exporter.addChild (modulePaths, -1, nullptr);
}
return exporter;
}
ValueTree PIPGenerator::createModuleChild (const String& moduleID)
{
ValueTree module (Ids::MODULE);
module.setProperty (Ids::ID, moduleID, nullptr);
module.setProperty (Ids::showAllCode, 1, nullptr);
module.setProperty (Ids::useLocalCopy, 0, nullptr);
module.setProperty (Ids::useGlobalPath, (getPathForModule (moduleID).isEmpty() ? 1 : 0), nullptr);
return module;
}
void PIPGenerator::addExporters (ValueTree& jucerTree)
{
ValueTree exportersTree (Ids::EXPORTFORMATS);
auto exporters = StringArray::fromTokens (metadata[Ids::exporters].toString(), ",", {});
for (auto& e : exporters)
{
e = e.trim().toUpperCase();
if (isValidExporterIdentifier (e))
exportersTree.addChild (createExporterChild (e), -1, nullptr);
}
jucerTree.addChild (exportersTree, -1, nullptr);
}
void PIPGenerator::addModules (ValueTree& jucerTree)
{
ValueTree modulesTree (Ids::MODULES);
auto modules = StringArray::fromTokens (metadata[Ids::dependencies_].toString(), ",", {});
modules.trim();
for (auto& m : modules)
modulesTree.addChild (createModuleChild (m.trim()), -1, nullptr);
jucerTree.addChild (modulesTree, -1, nullptr);
}
Result PIPGenerator::setProjectSettings (ValueTree& jucerTree)
{
auto setPropertyIfNotEmpty = [&jucerTree] (const Identifier& name, const var& value)
{
if (value != var())
jucerTree.setProperty (name, value, nullptr);
};
setPropertyIfNotEmpty (Ids::name, metadata[Ids::name]);
setPropertyIfNotEmpty (Ids::companyName, metadata[Ids::vendor]);
setPropertyIfNotEmpty (Ids::version, metadata[Ids::version]);
setPropertyIfNotEmpty (Ids::userNotes, metadata[Ids::description]);
setPropertyIfNotEmpty (Ids::companyWebsite, metadata[Ids::website]);
auto defines = metadata[Ids::defines].toString();
if (isJUCEExample (pipFile))
{
auto examplesDir = getExamplesDirectory();
if (examplesDir != File())
{
defines += ((defines.isEmpty() ? "" : " ") + String ("PIP_JUCE_EXAMPLES_DIRECTORY=")
+ Base64::toBase64 (examplesDir.getFullPathName()));
}
else
{
return Result::fail (String ("Invalid JUCE path. Set path to JUCE via ") +
(TargetOS::getThisOS() == TargetOS::osx ? "\"Projucer->Global Paths...\""
: "\"File->Global Paths...\"")
+ " menu item.");
}
jucerTree.setProperty (Ids::displaySplashScreen, true, nullptr);
}
setPropertyIfNotEmpty (Ids::defines, defines);
auto type = metadata[Ids::type].toString();
if (type == "Console")
{
jucerTree.setProperty (Ids::projectType, build_tools::ProjectType_ConsoleApp::getTypeName(), nullptr);
}
else if (type == "Component")
{
jucerTree.setProperty (Ids::projectType, build_tools::ProjectType_GUIApp::getTypeName(), nullptr);
}
else if (type == "AudioProcessor")
{
jucerTree.setProperty (Ids::projectType, build_tools::ProjectType_AudioPlugin::getTypeName(), nullptr);
jucerTree.setProperty (Ids::pluginAUIsSandboxSafe, "1", nullptr);
setPropertyIfNotEmpty (Ids::pluginManufacturer, metadata[Ids::vendor]);
StringArray pluginFormatsToBuild (Ids::buildVST3.toString(), Ids::buildAU.toString(), Ids::buildStandalone.toString());
pluginFormatsToBuild.addArray (getExtraPluginFormatsToBuild());
jucerTree.setProperty (Ids::pluginFormats, pluginFormatsToBuild.joinIntoString (","), nullptr);
const auto characteristics = metadata[Ids::pluginCharacteristics].toString();
if (characteristics.isNotEmpty())
jucerTree.setProperty (Ids::pluginCharacteristicsValue,
characteristics.removeCharacters (" \t\n\r"),
nullptr);
}
jucerTree.setProperty (Ids::useAppConfig, false, nullptr);
jucerTree.setProperty (Ids::addUsingNamespaceToJuceHeader, true, nullptr);
return Result::ok();
}
void PIPGenerator::setModuleFlags (ValueTree& jucerTree)
{
ValueTree options ("JUCEOPTIONS");
for (auto& option : StringArray::fromTokens (metadata[Ids::moduleFlags].toString(), ",", {}))
{
auto name = option.upToFirstOccurrenceOf ("=", false, true).trim();
auto value = option.fromFirstOccurrenceOf ("=", false, true).trim();
options.setProperty (name, (value == "1" ? 1 : 0), nullptr);
}
if (metadata[Ids::type].toString() == "AudioProcessor"
&& options.getPropertyPointer ("JUCE_VST3_CAN_REPLACE_VST2") == nullptr)
options.setProperty ("JUCE_VST3_CAN_REPLACE_VST2", 0, nullptr);
jucerTree.addChild (options, -1, nullptr);
}
String PIPGenerator::getMainFileTextForType()
{
const auto type = metadata[Ids::type].toString();
const auto mainTemplate = [&]
{
if (type == "Console")
return String (BinaryData::PIPConsole_cpp_in);
if (type == "Component")
return String (BinaryData::PIPComponent_cpp_in)
.replace ("${JUCE_PIP_NAME}", metadata[Ids::name].toString())
.replace ("${PROJECT_VERSION}", metadata[Ids::version].toString())
.replace ("${JUCE_PIP_MAIN_CLASS}", metadata[Ids::mainClass].toString());
if (type == "AudioProcessor")
return String (BinaryData::PIPAudioProcessor_cpp_in)
.replace ("${JUCE_PIP_MAIN_CLASS}", metadata[Ids::mainClass].toString());
return String{};
}();
if (mainTemplate.isEmpty())
return {};
const auto includeFilename = [&]
{
if (useLocalCopy) return pipFile.getFileName();
if (isTemp) return pipFile.getFullPathName();
return build_tools::RelativePath (pipFile,
outputDirectory.getChildFile ("Source"),
build_tools::RelativePath::unknown).toUnixStyle();
}();
return ensureCorrectWhitespace (mainTemplate.replace ("${JUCE_PIP_HEADER}", includeFilename));
}
//==============================================================================
Array<File> PIPGenerator::replaceRelativeIncludesAndGetFilesToMove()
{
StringArray lines;
pipFile.readLines (lines);
Array<File> files;
for (auto& line : lines)
{
if (line.contains ("#include") && ! line.contains ("JuceLibraryCode"))
{
auto path = line.fromFirstOccurrenceOf ("#include", false, false);
path = path.removeCharacters ("\"").trim();
if (path.startsWith ("<") && path.endsWith (">"))
continue;
auto file = pipFile.getParentDirectory().getChildFile (path);
files.add (file);
line = line.replace (path, file.getFileName());
}
}
outputDirectory.getChildFile ("Source")
.getChildFile (pipFile.getFileName())
.replaceWithText (joinLinesIntoSourceFile (lines));
return files;
}
bool PIPGenerator::copyRelativeFileToLocalSourceDirectory (const File& fileToCopy) const noexcept
{
return fileToCopy.copyFileTo (outputDirectory.getChildFile ("Source")
.getChildFile (fileToCopy.getFileName()));
}
StringArray PIPGenerator::getExtraPluginFormatsToBuild() const
{
auto tokens = StringArray::fromTokens (metadata[Ids::extraPluginFormats].toString(), ",", {});
for (auto& token : tokens)
{
token = [&]
{
if (token == "IAA")
return Ids::enableIAA.toString();
return "build" + token;
}();
}
return tokens;
}
String PIPGenerator::getPathForModule (const String& moduleID) const
{
if (isJUCEModule (moduleID))
{
if (juceModulesPath != File())
{
if (isTemp)
return juceModulesPath.getFullPathName();
return build_tools::RelativePath (juceModulesPath,
outputDirectory,
build_tools::RelativePath::projectFolder).toUnixStyle();
}
}
else if (availableUserModules != nullptr)
{
auto moduleRoot = availableUserModules->getModuleWithID (moduleID).second.getParentDirectory();
if (isTemp)
return moduleRoot.getFullPathName();
return build_tools::RelativePath (moduleRoot,
outputDirectory,
build_tools::RelativePath::projectFolder).toUnixStyle();
}
return {};
}
File PIPGenerator::getExamplesDirectory() const
{
if (juceModulesPath != File())
{
auto examples = juceModulesPath.getSiblingFile ("examples");
if (isValidJUCEExamplesDirectory (examples))
return examples;
}
auto examples = File (getAppSettings().getStoredPath (Ids::jucePath, TargetOS::getThisOS()).get().toString()).getChildFile ("examples");
if (isValidJUCEExamplesDirectory (examples))
return examples;
return {};
}

View File

@ -0,0 +1,86 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../Helpers/jucer_MiscUtilities.h"
#include "../../Project/Modules/jucer_AvailableModulesList.h"
//==============================================================================
class PIPGenerator
{
public:
PIPGenerator (const File& pipFile, const File& outputDirectory = {},
const File& pathToJUCEModules = {}, const File& pathToUserModules = {});
//==============================================================================
bool hasValidPIP() const noexcept { return ! metadata[Ids::name].toString().isEmpty(); }
File getJucerFile() const noexcept { return outputDirectory.getChildFile (metadata[Ids::name].toString() + ".jucer"); }
File getPIPFile() const noexcept { return useLocalCopy ? outputDirectory.getChildFile ("Source").getChildFile (pipFile.getFileName()) : pipFile; }
String getMainClassName() const noexcept { return metadata[Ids::mainClass]; }
File getOutputDirectory() const noexcept { return outputDirectory; }
//==============================================================================
Result createJucerFile();
Result createMainCpp();
private:
//==============================================================================
void addFileToTree (ValueTree& groupTree, const String& name, bool compile, const String& path);
void createFiles (ValueTree& jucerTree);
ValueTree createModulePathChild (const String& moduleID);
ValueTree createBuildConfigChild (bool isDebug);
ValueTree createExporterChild (const Identifier& exporterIdentifier);
ValueTree createModuleChild (const String& moduleID);
void addExporters (ValueTree& jucerTree);
void addModules (ValueTree& jucerTree);
Result setProjectSettings (ValueTree& jucerTree);
void setModuleFlags (ValueTree& jucerTree);
String getMainFileTextForType();
//==============================================================================
Array<File> replaceRelativeIncludesAndGetFilesToMove();
bool copyRelativeFileToLocalSourceDirectory (const File&) const noexcept;
StringArray getExtraPluginFormatsToBuild() const;
String getPathForModule (const String&) const;
File getExamplesDirectory() const;
//==============================================================================
File pipFile, outputDirectory, juceModulesPath, userModulesPath;
std::unique_ptr<AvailableModulesList> availableUserModules;
var metadata;
bool isTemp = false, useLocalCopy = false;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (PIPGenerator)
};

View File

@ -0,0 +1,224 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
struct ColourPropertyComponent : public PropertyComponent
{
ColourPropertyComponent (UndoManager* undoManager, const String& name, const Value& colour,
Colour defaultColour, bool canResetToDefault)
: PropertyComponent (name),
colourEditor (undoManager, colour, defaultColour, canResetToDefault)
{
addAndMakeVisible (colourEditor);
}
void resized() override
{
colourEditor.setBounds (getLookAndFeel().getPropertyComponentContentPosition (*this));
}
void refresh() override {}
private:
/**
A component that shows a colour swatch with hex ARGB value, and which pops up
a colour selector when you click it.
*/
struct ColourEditorComponent : public Component,
private Value::Listener
{
ColourEditorComponent (UndoManager* um, const Value& colour,
Colour defaultCol, const bool canReset)
: undoManager (um), colourValue (colour), defaultColour (defaultCol),
canResetToDefault (canReset)
{
colourValue.addListener (this);
}
void paint (Graphics& g) override
{
const Colour colour (getColour());
g.fillAll (Colours::grey);
g.fillCheckerBoard (getLocalBounds().reduced (2).toFloat(),
10.0f, 10.0f,
Colour (0xffdddddd).overlaidWith (colour),
Colour (0xffffffff).overlaidWith (colour));
g.setColour (Colours::white.overlaidWith (colour).contrasting());
g.setFont (Font ((float) getHeight() * 0.6f, Font::bold));
g.drawFittedText (colour.toDisplayString (true), getLocalBounds().reduced (2, 1),
Justification::centred, 1);
}
Colour getColour() const
{
if (colourValue.toString().isEmpty())
return defaultColour;
return Colour::fromString (colourValue.toString());
}
void setColour (Colour newColour)
{
if (getColour() != newColour)
{
if (newColour == defaultColour && canResetToDefault)
colourValue = var();
else
colourValue = newColour.toDisplayString (true);
}
}
void resetToDefault()
{
setColour (defaultColour);
}
void refresh()
{
const Colour col (getColour());
if (col != lastColour)
{
lastColour = col;
repaint();
}
}
void mouseDown (const MouseEvent&) override
{
if (undoManager != nullptr)
undoManager->beginNewTransaction();
CallOutBox::launchAsynchronously (std::make_unique<PopupColourSelector> (colourValue,
defaultColour,
canResetToDefault),
getScreenBounds(),
nullptr);
}
private:
void valueChanged (Value&) override
{
refresh();
}
UndoManager* undoManager;
Value colourValue;
Colour lastColour;
const Colour defaultColour;
const bool canResetToDefault;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourEditorComponent)
};
//==============================================================================
struct PopupColourSelector : public Component,
private ChangeListener,
private Value::Listener
{
PopupColourSelector (const Value& colour,
Colour defaultCol,
const bool canResetToDefault)
: defaultButton ("Reset to Default"),
colourValue (colour),
defaultColour (defaultCol)
{
addAndMakeVisible (selector);
selector.setName ("Colour");
selector.setCurrentColour (getColour());
selector.addChangeListener (this);
if (canResetToDefault)
{
addAndMakeVisible (defaultButton);
defaultButton.onClick = [this]
{
setColour (defaultColour);
selector.setCurrentColour (defaultColour);
};
}
colourValue.addListener (this);
setSize (300, 400);
}
void resized() override
{
if (defaultButton.isVisible())
{
selector.setBounds (0, 0, getWidth(), getHeight() - 30);
defaultButton.changeWidthToFitText (22);
defaultButton.setTopLeftPosition (10, getHeight() - 26);
}
else
{
selector.setBounds (getLocalBounds());
}
}
Colour getColour() const
{
if (colourValue.toString().isEmpty())
return defaultColour;
return Colour::fromString (colourValue.toString());
}
void setColour (Colour newColour)
{
if (getColour() != newColour)
{
if (newColour == defaultColour && defaultButton.isVisible())
colourValue = var();
else
colourValue = newColour.toDisplayString (true);
}
}
private:
void changeListenerCallback (ChangeBroadcaster*) override
{
if (selector.getCurrentColour() != getColour())
setColour (selector.getCurrentColour());
}
void valueChanged (Value&) override
{
selector.setCurrentColour (getColour());
}
StoredSettings::ColourSelectorWithSwatches selector;
TextButton defaultButton;
Value colourValue;
Colour defaultColour;
};
ColourEditorComponent colourEditor;
};

View File

@ -0,0 +1,245 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
/** A PropertyComponent for selecting files or folders.
The user may drag files over the property box, enter the path manually and/or click
the '...' button to open a file selection dialog box.
*/
class FilePathPropertyComponent : public PropertyComponent,
public FileDragAndDropTarget,
protected Value::Listener
{
public:
FilePathPropertyComponent (Value valueToControl, const String& propertyName, bool isDir, bool thisOS = true,
const String& wildcardsToUse = "*", const File& relativeRoot = File())
: PropertyComponent (propertyName),
text (valueToControl, propertyName, 1024, false),
isDirectory (isDir), isThisOS (thisOS), wildcards (wildcardsToUse), root (relativeRoot)
{
textValue.referTo (valueToControl);
init();
}
/** Displays a default value when no value is specified by the user. */
FilePathPropertyComponent (ValueWithDefault& valueToControl, const String& propertyName, bool isDir, bool thisOS = true,
const String& wildcardsToUse = "*", const File& relativeRoot = File())
: PropertyComponent (propertyName),
text (valueToControl, propertyName, 1024, false),
isDirectory (isDir), isThisOS (thisOS), wildcards (wildcardsToUse), root (relativeRoot)
{
textValue = valueToControl.getPropertyAsValue();
init();
}
//==============================================================================
void refresh() override {}
void resized() override
{
auto bounds = getLocalBounds();
text.setBounds (bounds.removeFromLeft (jmax (400, bounds.getWidth() - 55)));
bounds.removeFromLeft (5);
browseButton.setBounds (bounds);
}
void paintOverChildren (Graphics& g) override
{
if (highlightForDragAndDrop)
{
g.setColour (findColour (defaultHighlightColourId).withAlpha (0.5f));
g.fillRect (getLookAndFeel().getPropertyComponentContentPosition (text));
}
}
//==============================================================================
bool isInterestedInFileDrag (const StringArray&) override { return true; }
void fileDragEnter (const StringArray&, int, int) override { highlightForDragAndDrop = true; repaint(); }
void fileDragExit (const StringArray&) override { highlightForDragAndDrop = false; repaint(); }
void filesDropped (const StringArray& selectedFiles, int, int) override
{
setTo (selectedFiles[0]);
highlightForDragAndDrop = false;
repaint();
}
protected:
void valueChanged (Value&) override
{
updateEditorColour();
}
private:
//==============================================================================
void init()
{
textValue.addListener (this);
text.setInterestedInFileDrag (false);
addAndMakeVisible (text);
browseButton.onClick = [this] { browse(); };
addAndMakeVisible (browseButton);
lookAndFeelChanged();
}
void setTo (File f)
{
if (isDirectory && ! f.isDirectory())
f = f.getParentDirectory();
auto pathName = (root == File()) ? f.getFullPathName()
: f.getRelativePathFrom (root);
text.setText (pathName);
updateEditorColour();
}
void browse()
{
File currentFile = {};
if (text.getText().isNotEmpty())
currentFile = root.getChildFile (text.getText());
if (isDirectory)
{
chooser = std::make_unique<FileChooser> ("Select directory", currentFile);
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectDirectories;
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
{
if (fc.getResult() == File{})
return;
setTo (fc.getResult());
});
}
else
{
chooser = std::make_unique<FileChooser> ("Select file", currentFile, wildcards);
auto chooserFlags = FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles;
chooser->launchAsync (chooserFlags, [this] (const FileChooser& fc)
{
if (fc.getResult() == File{})
return;
setTo (fc.getResult());
});
}
}
void updateEditorColour()
{
if (isThisOS)
{
text.setColour (TextPropertyComponent::textColourId, findColour (widgetTextColourId));
auto pathToCheck = text.getText();
if (pathToCheck.isNotEmpty())
{
pathToCheck.replace ("${user.home}", "~");
#if JUCE_WINDOWS
if (pathToCheck.startsWith ("~"))
pathToCheck = pathToCheck.replace ("~", File::getSpecialLocation (File::userHomeDirectory).getFullPathName());
#endif
if (! root.getChildFile (pathToCheck).exists())
text.setColour (TextPropertyComponent::textColourId, Colours::red);
}
}
}
void lookAndFeelChanged() override
{
browseButton.setColour (TextButton::buttonColourId, findColour (secondaryButtonBackgroundColourId));
browseButton.setColour (TextButton::textColourOffId, Colours::white);
updateEditorColour();
}
//==============================================================================
Value textValue;
TextPropertyComponent text;
TextButton browseButton { "..." };
bool isDirectory, isThisOS, highlightForDragAndDrop = false;
String wildcards;
File root;
std::unique_ptr<FileChooser> chooser;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FilePathPropertyComponent)
};
//==============================================================================
class FilePathPropertyComponentWithEnablement : public FilePathPropertyComponent
{
public:
FilePathPropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
bool isDir,
bool thisOS = true,
const String& wildcardsToUse = "*",
const File& relativeRoot = File())
: FilePathPropertyComponent (valueToControl,
propertyName,
isDir,
thisOS,
wildcardsToUse,
relativeRoot),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~FilePathPropertyComponentWithEnablement() override { value.removeListener (this); }
private:
void valueChanged (Value& v) override
{
FilePathPropertyComponent::valueChanged (v);
setEnabled (valueWithDefault.get());
}
ValueWithDefault valueWithDefault;
Value value;
};

View File

@ -0,0 +1,73 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
class LabelPropertyComponent : public PropertyComponent
{
public:
LabelPropertyComponent (const String& labelText, int propertyHeight = 25,
Font labelFont = Font (16.0f, Font::bold),
Justification labelJustification = Justification::centred)
: PropertyComponent (labelText),
labelToDisplay ({}, labelText)
{
setPreferredHeight (propertyHeight);
labelToDisplay.setJustificationType (labelJustification);
labelToDisplay.setFont (labelFont);
addAndMakeVisible (labelToDisplay);
setLookAndFeel (&lf);
}
~LabelPropertyComponent() override { setLookAndFeel (nullptr); }
//==============================================================================
void refresh() override {}
void resized() override
{
labelToDisplay.setBounds (getLocalBounds());
}
private:
//==============================================================================
struct LabelLookAndFeel : public ProjucerLookAndFeel
{
void drawPropertyComponentLabel (Graphics&, int, int, PropertyComponent&) {}
};
void lookAndFeelChanged() override
{
labelToDisplay.setColour (Label::textColourId, ProjucerApplication::getApp().lookAndFeel.findColour (defaultTextColourId));
}
//==============================================================================
LabelLookAndFeel lf;
Label labelToDisplay;
};

View File

@ -0,0 +1,160 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
class TextPropertyComponentWithEnablement : public TextPropertyComponent,
private Value::Listener
{
public:
TextPropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
int maxNumChars,
bool multiLine)
: TextPropertyComponent (valueToControl, propertyName, maxNumChars, multiLine),
valueWithDefault (valueToListenTo),
value (valueWithDefault.getPropertyAsValue())
{
value.addListener (this);
setEnabled (valueWithDefault.get());
}
~TextPropertyComponentWithEnablement() override { value.removeListener (this); }
private:
ValueWithDefault valueWithDefault;
Value value;
void valueChanged (Value&) override { setEnabled (valueWithDefault.get()); }
};
//==============================================================================
class ChoicePropertyComponentWithEnablement : public ChoicePropertyComponent,
private Value::Listener
{
public:
ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
const StringArray& choiceToUse,
const Array<var>& correspondingValues)
: ChoicePropertyComponent (valueToControl, propertyName, choiceToUse, correspondingValues),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const Identifier& multiChoiceID,
const String& propertyName,
const StringArray& choicesToUse,
const Array<var>& correspondingValues)
: ChoicePropertyComponentWithEnablement (valueToControl, valueToListenTo, propertyName, choicesToUse, correspondingValues)
{
jassert (valueToListenTo.get().getArray() != nullptr);
isMultiChoice = true;
idToCheck = multiChoiceID;
valueChanged (value);
}
ChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName)
: ChoicePropertyComponent (valueToControl, propertyName),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~ChoicePropertyComponentWithEnablement() override { value.removeListener (this); }
private:
ValueWithDefault valueWithDefault;
Value value;
bool isMultiChoice = false;
Identifier idToCheck;
bool checkMultiChoiceVar() const
{
jassert (isMultiChoice);
auto v = valueWithDefault.get();
if (auto* varArray = v.getArray())
return varArray->contains (idToCheck.toString());
jassertfalse;
return false;
}
void valueChanged (Value&) override
{
if (isMultiChoice)
setEnabled (checkMultiChoiceVar());
else
setEnabled (valueWithDefault.get());
}
};
//==============================================================================
class MultiChoicePropertyComponentWithEnablement : public MultiChoicePropertyComponent,
private Value::Listener
{
public:
MultiChoicePropertyComponentWithEnablement (ValueWithDefault& valueToControl,
ValueWithDefault valueToListenTo,
const String& propertyName,
const StringArray& choices,
const Array<var>& correspondingValues)
: MultiChoicePropertyComponent (valueToControl,
propertyName,
choices,
correspondingValues),
valueWithDefault (valueToListenTo),
value (valueToListenTo.getPropertyAsValue())
{
value.addListener (this);
valueChanged (value);
}
~MultiChoicePropertyComponentWithEnablement() override { value.removeListener (this); }
private:
void valueChanged (Value&) override { setEnabled (valueWithDefault.get()); }
ValueWithDefault valueWithDefault;
Value value;
};

View File

@ -0,0 +1,136 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
class IconButton : public Button
{
public:
IconButton (String buttonName, Image imageToDisplay)
: Button (buttonName),
iconImage (imageToDisplay)
{
setTooltip (buttonName);
}
IconButton (String buttonName, Path pathToDisplay)
: Button (buttonName),
iconPath (pathToDisplay),
iconImage (createImageFromPath (iconPath))
{
setTooltip (buttonName);
}
void setImage (Image newImage)
{
iconImage = newImage;
repaint();
}
void setPath (Path newPath)
{
iconImage = createImageFromPath (newPath);
repaint();
}
void setBackgroundColour (Colour backgroundColourToUse)
{
backgroundColour = backgroundColourToUse;
usingNonDefaultBackgroundColour = true;
}
void setIconInset (int newIconInset)
{
iconInset = newIconInset;
repaint();
}
void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown) override
{
float alpha = 1.0f;
if (! isEnabled())
{
isMouseOverButton = false;
isButtonDown = false;
alpha = 0.2f;
}
auto fill = isButtonDown ? backgroundColour.darker (0.5f)
: isMouseOverButton ? backgroundColour.darker (0.2f)
: backgroundColour;
auto bounds = getLocalBounds();
if (isButtonDown)
bounds.reduce (2, 2);
Path ellipse;
ellipse.addEllipse (bounds.toFloat());
g.reduceClipRegion (ellipse);
g.setColour (fill.withAlpha (alpha));
g.fillAll();
g.setOpacity (alpha);
g.drawImage (iconImage, bounds.reduced (iconInset).toFloat(), RectanglePlacement::fillDestination, false);
}
private:
void lookAndFeelChanged() override
{
if (! usingNonDefaultBackgroundColour)
backgroundColour = findColour (defaultButtonBackgroundColourId);
if (iconPath != Path())
iconImage = createImageFromPath (iconPath);
repaint();
}
Image createImageFromPath (Path path)
{
Image image (Image::ARGB, 250, 250, true);
Graphics g (image);
g.setColour (findColour (defaultIconColourId));
g.fillPath (path, RectanglePlacement (RectanglePlacement::centred)
.getTransformToFit (path.getBounds(), image.getBounds().toFloat()));
return image;
}
Path iconPath;
Image iconImage;
Colour backgroundColour { findColour (defaultButtonBackgroundColourId) };
bool usingNonDefaultBackgroundColour = false;
int iconInset = 2;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IconButton)
};

View File

@ -0,0 +1,668 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "../../Application/jucer_Application.h"
#include "jucer_Icons.h"
const Icons& getIcons()
{
return *ProjucerApplication::getApp().icons;
}
namespace IconPathData
{
const uint8 imageDoc[] = { 110,109,255,255,249,67,255,255,249,67,108,0,0,0,0,255,255,249,67,108,0,0,0,0,0,0,0,0,108,255,255,249,67,0,0,0,0,108,255,255,249,67,255,255,249,67,99,109,72,62,243,66,56,152,66,67,98,158,117,31,67,56,152,66,67,82,228,63,67,132,41,34,67,82,228,63,67,12,
166,248,66,98,82,228,63,67,20,249,172,66,158,117,31,67,84,55,88,66,68,62,243,66,84,55,88,66,98,76,145,167,66,84,55,88,66,192,103,77,66,16,249,172,66,192,103,77,66,12,166,248,66,98,200,103,77,66,132,41,34,67,132,41,162,66,56,152,66,67,72,62,243,66,56,
152,66,67,99,109,137,124,236,67,221,96,128,67,108,49,69,170,67,12,166,248,66,108,214,13,26,67,200,103,155,67,108,0,0,200,66,221,96,128,67,108,56,152,194,65,89,55,166,67,108,56,152,194,65,137,124,236,67,108,153,34,235,67,137,124,236,67,108,153,34,235,
67,221,96,128,67,99,101,0,0 };
const uint8 config[] = { 110,109,149,118,142,67,134,71,167,67,108,59,28,135,67,149,118,142,67,98,210,242,136,67,254,159,140,67,104,201,138,67,104,201,138,67,255,159,140,67,209,242,136,67,108,240,112,165,67,43,77,144,67,98,210,50,168,67,254,159,140,67,105,9,170,67,134,7,136,67,
74,203,172,67,89,90,132,67,108,104,105,154,67,238,240,99,67,98,180,84,155,67,42,109,94,67,255,63,156,67,102,233,88,67,255,63,156,67,162,101,83,67,108,240,16,181,67,134,135,70,67,98,240,16,181,67,194,3,65,67,240,16,181,67,148,86,61,67,240,16,181,67,208,
210,55,67,98,240,16,181,67,12,79,50,67,240,16,181,67,224,161,46,67,240,16,181,67,28,30,41,67,108,255,63,156,67,254,63,28,67,98,180,84,155,67,58,188,22,67,180,84,155,67,118,56,17,67,104,105,154,67,178,180,11,67,108,74,203,172,67,223,225,205,66,98,179,
244,170,67,253,127,187,66,210,50,168,67,72,203,172,66,240,112,165,67,147,22,158,66,108,255,159,140,67,253,127,187,66,98,104,201,138,67,163,37,180,66,210,242,136,67,72,203,172,66,59,28,135,67,238,112,165,66,108,149,118,142,67,86,90,4,66,98,104,201,138,
67,144,150,220,65,239,48,134,67,40,45,191,65,195,131,130,67,8,15,147,65,108,195,67,96,67,146,150,92,66,98,255,191,90,67,56,60,85,66,59,60,85,67,222,225,77,66,120,184,79,67,222,225,77,66,108,90,218,66,67,0,75,235,63,98,150,86,61,67,0,75,235,63,105,169,
57,67,0,75,235,63,165,37,52,67,0,75,235,63,98,225,161,46,67,0,75,235,63,180,244,42,67,0,75,235,63,240,112,37,67,0,75,235,63,108,211,146,24,67,222,225,77,66,98,15,15,19,67,56,60,85,66,75,139,13,67,56,60,85,66,136,7,8,67,146,150,92,66,108,136,135,198,66,
8,15,147,65,98,254,127,187,66,44,45,191,65,74,203,172,66,152,150,220,65,148,22,158,66,90,90,4,66,108,254,127,187,66,240,112,165,66,98,118,120,176,66,75,203,172,66,28,30,169,66,165,37,180,66,194,195,161,66,45,45,191,66,108,250,255,249,65,195,195,161,66,
98,222,225,205,65,119,120,176,66,116,120,176,65,45,45,191,66,86,90,132,65,15,143,209,66,108,59,60,85,66,74,139,13,67,98,225,225,77,66,14,15,19,67,135,135,70,66,210,146,24,67,135,135,70,66,148,22,30,67,108,0,0,0,0,178,244,42,67,98,0,0,0,0,118,120,48,67,
0,0,0,0,164,37,52,67,0,0,0,0,104,169,57,67,98,0,0,0,0,44,45,63,67,0,0,0,0,88,218,66,67,0,0,0,0,28,94,72,67,108,135,135,70,66,58,60,85,67,98,225,225,77,66,254,191,90,67,225,225,77,66,194,67,96,67,59,60,85,66,134,199,101,67,108,88,90,132,65,164,69,133,
67,98,194,195,161,65,29,222,137,67,224,225,205,65,74,139,141,67,254,255,249,65,119,56,145,67,108,194,195,161,66,29,222,137,67,98,28,30,169,66,180,180,139,67,120,120,176,66,74,139,141,67,210,210,183,66,225,97,143,67,108,104,105,154,66,210,50,168,67,98,
28,30,169,66,179,244,170,67,254,127,187,66,74,203,172,67,178,52,202,66,44,141,175,67,108,29,222,9,67,74,43,157,67,98,225,97,15,67,150,22,158,67,165,229,20,67,225,1,159,67,103,105,26,67,225,1,159,67,108,133,71,39,67,210,210,183,67,98,73,203,44,67,210,
210,183,67,118,120,48,67,210,210,183,67,58,252,53,67,210,210,183,67,98,254,127,59,67,210,210,183,67,43,45,63,67,210,210,183,67,239,176,68,67,210,210,183,67,108,13,143,81,67,225,1,159,67,98,209,18,87,67,150,22,158,67,148,150,92,67,150,22,158,67,87,26,
98,67,74,43,157,67,108,13,111,131,67,44,141,175,67,98,239,48,134,67,255,223,171,67,104,201,138,67,105,9,170,67,149,118,142,67,134,71,167,67,99,109,59,252,53,67,210,82,118,67,98,15,15,19,67,210,82,118,67,118,248,238,66,0,192,90,67,118,248,238,66,210,210,
55,67,98,118,248,238,66,166,229,20,67,13,15,19,67,167,165,242,66,58,252,53,67,167,165,242,66,98,102,233,88,67,167,165,242,66,57,124,116,67,166,229,20,67,57,124,116,67,210,210,55,67,98,57,124,116,67,0,192,90,67,104,233,88,67,210,82,118,67,59,252,53,67,
210,82,118,67,99,109,178,116,233,67,75,107,188,67,98,178,116,233,67,210,210,183,67,103,137,232,67,14,79,178,67,27,158,231,67,74,203,172,67,108,163,165,242,67,0,64,156,67,98,11,207,240,67,211,146,152,67,117,248,238,67,240,208,149,67,223,33,237,67,15,15,
147,67,108,178,212,217,67,60,188,150,67,98,133,39,214,67,15,15,147,67,12,143,209,67,120,56,145,67,148,246,204,67,150,118,142,67,108,208,114,199,67,210,82,118,67,98,163,197,195,67,60,124,116,67,118,24,192,67,60,124,116,67,72,107,188,67,60,124,116,67,108,
87,58,179,67,180,180,139,67,98,118,120,176,67,255,159,140,67,147,182,173,67,255,159,140,67,253,223,171,67,75,139,141,67,98,28,30,169,67,150,118,142,67,133,71,167,67,226,97,143,67,238,112,165,67,120,56,145,67,108,194,35,146,67,180,180,139,67,98,224,97,
143,67,149,118,142,67,254,159,140,67,44,77,144,67,104,201,138,67,89,250,147,67,108,13,15,147,67,59,92,166,67,98,44,77,144,67,179,244,170,67,224,97,143,67,44,141,175,67,149,118,142,67,240,16,181,67,108,255,255,121,67,44,45,191,67,98,255,255,121,67,89,
218,194,67,149,214,123,67,134,135,198,67,43,173,125,67,180,52,202,67,108,194,35,146,67,44,205,206,67,98,89,250,147,67,165,101,211,67,58,188,150,67,29,254,215,67,103,105,154,67,74,171,219,67,108,58,188,150,67,120,248,238,67,98,28,126,153,67,14,207,240,
67,74,43,157,67,164,165,242,67,43,237,159,67,60,124,244,67,108,43,141,175,67,105,137,232,67,98,164,37,180,67,181,116,233,67,104,169,185,67,0,96,234,67,44,45,191,67,0,96,234,67,108,149,246,204,67,182,20,249,67,98,44,205,206,67,106,41,248,67,194,163,208,
67,106,41,248,67,89,122,210,67,30,62,247,67,98,240,80,212,67,210,82,246,67,58,60,213,67,210,82,246,67,209,18,215,67,136,103,245,67,108,209,18,215,67,14,47,225,67,98,74,171,219,67,45,109,222,67,43,109,222,67,255,191,218,67,89,26,226,67,134,39,214,67,108,
211,82,246,67,59,60,213,67,98,105,41,248,67,14,143,209,67,179,20,249,67,43,205,206,67,255,255,249,67,254,31,203,67,108,178,116,233,67,75,107,188,67,99,109,89,218,194,67,44,205,206,67,98,209,210,183,67,165,101,211,67,254,223,171,67,225,225,205,67,134,
71,167,67,90,218,194,67,98,14,175,162,67,211,210,183,67,210,50,168,67,0,224,171,67,88,58,179,67,136,71,167,67,98,224,65,190,67,15,175,162,67,178,52,202,67,211,50,168,67,43,205,206,67,90,58,179,67,98,163,101,211,67,225,65,190,67,223,225,205,67,180,52,
202,67,89,218,194,67,44,205,206,67,99,101,0,0 };
const uint8 graph[] = { 110,109,166,158,186,66,184,11,143,67,108,113,151,95,67,98,243,92,67,108,113,151,95,67,228,55,54,67,108,206,129,81,67,228,55,54,67,98,253,118,74,67,228,55,54,67,44,108,67,67,47,117,52,67,91,97,60,67,123,178,50,67,108,91,97,60,67,239,210,71,67,108,245,
100,104,66,127,123,132,67,108,245,100,104,66,181,2,158,67,108,166,158,186,66,181,2,158,67,108,166,158,186,66,184,11,143,67,99,109,97,243,220,67,180,2,158,67,108,97,243,220,67,126,123,132,67,108,83,207,155,67,238,210,71,67,108,83,207,155,67,122,178,50,
67,98,235,73,152,67,227,55,54,67,130,196,148,67,227,55,54,67,25,63,145,67,227,55,54,67,108,72,52,138,67,227,55,54,67,108,72,52,138,67,97,243,92,67,108,87,88,203,67,184,11,143,67,108,87,88,203,67,181,2,158,67,108,97,243,220,67,181,2,158,67,99,109,133,
205,133,67,180,2,158,67,108,133,205,133,67,150,250,55,67,108,247,100,104,67,150,250,55,67,108,247,100,104,67,180,2,158,67,108,133,205,133,67,180,2,158,67,99,109,245,100,232,67,57,208,166,67,108,194,230,191,67,57,208,166,67,98,226,55,182,67,57,208,166,
67,183,75,174,67,100,188,174,67,183,75,174,67,68,107,184,67,108,183,75,174,67,119,233,224,67,98,183,75,174,67,87,152,234,67,226,55,182,67,130,132,242,67,194,230,191,67,130,132,242,67,108,245,100,232,67,130,132,242,67,98,213,19,242,67,130,132,242,67,255,
255,249,67,87,152,234,67,255,255,249,67,119,233,224,67,108,255,255,249,67,68,107,184,67,98,255,255,249,67,100,188,174,67,213,19,242,67,57,208,166,67,245,100,232,67,57,208,166,67,99,109,246,100,232,66,57,208,166,67,108,83,216,12,66,57,208,166,67,98,92,
133,125,65,57,208,166,67,0,0,128,183,100,188,174,67,0,0,128,183,68,107,184,67,108,0,0,128,183,119,233,224,67,98,0,0,128,183,87,152,234,67,92,133,125,65,130,132,242,67,83,216,12,66,130,132,242,67,108,246,100,232,66,130,132,242,67,98,58,144,7,67,130,132,
242,67,144,104,23,67,87,152,234,67,144,104,23,67,119,233,224,67,108,144,104,23,67,68,107,184,67,98,144,104,23,67,100,188,174,67,57,144,7,67,57,208,166,67,246,100,232,66,57,208,166,67,99,109,205,129,81,67,139,95,38,67,108,25,63,145,67,139,95,38,67,98,
249,237,154,67,139,95,38,67,36,218,162,67,53,135,22,67,36,218,162,67,118,41,3,67,108,36,218,162,67,68,180,72,66,98,36,218,162,67,139,122,246,65,249,237,154,67,176,111,111,65,25,63,145,67,176,111,111,65,108,205,129,81,67,176,111,111,65,98,13,36,62,67,
176,111,111,65,183,75,46,67,139,122,246,65,183,75,46,67,68,180,72,66,108,183,75,46,67,118,41,3,67,98,183,75,46,67,53,135,22,67,15,36,62,67,139,95,38,67,205,129,81,67,139,95,38,67,99,109,25,63,145,67,57,208,166,67,108,205,129,81,67,57,208,166,67,98,13,
36,62,67,57,208,166,67,183,75,46,67,100,188,174,67,183,75,46,67,68,107,184,67,108,183,75,46,67,119,233,224,67,98,183,75,46,67,87,152,234,67,13,36,62,67,130,132,242,67,205,129,81,67,130,132,242,67,108,25,63,145,67,130,132,242,67,98,249,237,154,67,130,
132,242,67,36,218,162,67,87,152,234,67,36,218,162,67,119,233,224,67,108,36,218,162,67,68,107,184,67,98,36,218,162,67,100,188,174,67,249,237,154,67,57,208,166,67,25,63,145,67,57,208,166,67,99,101,0,0 };
const uint8 info[] = { 110,109,0,0,122,67,0,0,0,0,98,79,35,224,66,0,0,0,0,0,0,0,0,79,35,224,66,0,0,0,0,0,0,122,67,98,0,0,0,0,44,247,193,67,79,35,224,66,0,0,250,67,0,0,122,67,0,0,250,67,98,44,247,193,67,0,0,250,67,0,0,250,67,44,247,193,67,0,0,250,67,0,0,122,67,98,0,0,250,67,
79,35,224,66,44,247,193,67,0,0,0,0,0,0,122,67,0,0,0,0,99,109,114,79,101,67,79,35,224,66,108,71,88,135,67,79,35,224,66,108,71,88,135,67,132,229,28,67,108,116,79,101,67,132,229,28,67,108,116,79,101,67,79,35,224,66,99,109,79,35,149,67,106,132,190,67,108,
98,185,123,67,106,132,190,67,98,150,123,106,67,106,132,190,67,176,220,97,67,168,17,187,67,176,220,97,67,18,150,177,67,108,176,220,97,67,248,52,108,67,98,176,220,97,67,212,8,103,67,238,105,94,67,18,150,99,67,204,61,89,67,18,150,99,67,108,98,185,73,67,
18,150,99,67,108,98,185,73,67,88,238,59,67,108,160,70,120,67,88,238,59,67,98,54,194,132,67,88,238,59,67,169,17,137,67,60,141,68,67,169,17,137,67,8,203,85,67,108,169,17,137,67,26,97,166,67,98,169,17,137,67,43,247,168,67,10,203,138,67,141,176,170,67,27,
97,141,67,141,176,170,67,108,80,35,149,67,141,176,170,67,108,80,35,149,67,106,132,190,67,99,101,0,0 };
const uint8 warning[] = { 110,109,211,238,239,67,40,5,203,67,108,193,13,208,67,108,125,148,67,98,86,211,198,67,31,182,131,67,204,226,182,67,70,187,81,67,98,168,173,67,172,44,48,67,108,79,199,141,67,106,58,134,66,98,228,140,132,67,104,58,6,66,182,56,105,67,104,58,6,66,225,195,
86,67,106,58,134,66,108,185,1,23,67,171,44,48,67,98,228,140,4,67,69,187,81,67,161,87,201,66,30,182,131,67,247,109,164,66,108,125,148,67,108,170,166,147,65,40,5,203,67,98,0,0,0,0,118,204,219,67,89,156,113,65,180,56,233,67,222,195,86,66,180,56,233,67,108,
133,39,223,67,180,56,233,67,98,90,156,241,67,180,56,233,67,1,0,250,67,178,245,218,67,211,238,239,67,40,5,203,67,99,109,167,99,133,67,206,104,211,67,108,165,221,101,67,206,104,211,67,108,165,221,101,67,248,243,192,67,108,167,99,133,67,248,243,192,67,108,
167,99,133,67,206,104,211,67,99,109,227,140,132,67,186,135,179,67,108,44,139,103,67,186,135,179,67,108,29,48,100,67,174,178,76,67,108,107,58,134,67,174,178,76,67,108,227,140,132,67,186,135,179,67,99,101,0,0 };
const uint8 user[] = { 110,109,0,0,128,65,0,0,160,65,98,0,0,128,65,0,0,112,65,68,177,70,65,0,0,48,65,0,0,0,65,0,0,48,65,98,238,58,101,64,0,0,48,65,0,0,0,0,0,0,120,65,0,0,0,0,0,0,160,65,108,0,0,128,65,0,0,160,65,99,109,0,0,80,65,0,0,160,64,108,0,0,80,65,0,0,160,64,108,104,230,
79,65,38,255,167,64,108,176,153,79,65,45,249,175,64,108,8,26,79,65,251,232,183,64,108,196,103,78,65,125,201,191,64,108,84,131,77,65,168,149,199,64,108,75,109,76,65,128,72,207,64,108,91,38,75,65,21,221,214,64,108,85,175,73,65,144,78,222,64,108,40,9,72,
65,46,152,229,64,108,229,52,70,65,66,181,236,64,108,180,51,68,65,66,161,243,64,108,225,6,66,65,190,87,250,64,108,205,175,63,65,54,106,0,65,108,250,47,61,65,146,137,3,65,108,255,136,58,65,244,135,6,65,108,144,188,55,65,114,99,9,65,108,119,204,52,65,54,
26,12,65,108,150,186,49,65,135,170,14,65,108,226,136,46,65,190,18,17,65,108,104,57,43,65,81,81,19,65,108,69,206,39,65,210,100,21,65,108,170,73,36,65,235,75,23,65,108,215,173,32,65,102,5,25,65,108,27,253,28,65,39,144,26,65,108,210,57,25,65,50,235,27,65,
108,102,102,21,65,170,21,29,65,108,72,133,17,65,207,14,30,65,108,243,152,13,65,2,214,30,65,108,236,163,9,65,194,106,31,65,108,185,168,5,65,178,204,31,65,108,232,169,1,65,146,251,31,65,108,255,255,255,64,0,0,32,65,108,0,0,0,65,0,0,32,65,108,255,255,255,
64,0,0,32,65,108,218,0,248,64,104,230,31,65,108,211,6,240,64,176,153,31,65,108,4,23,232,64,8,26,31,65,108,130,54,224,64,196,103,30,65,108,87,106,216,64,84,131,29,65,108,128,183,208,64,75,109,28,65,108,234,34,201,64,91,38,27,65,108,112,177,193,64,85,175,
25,65,108,211,103,186,64,41,9,24,65,108,190,74,179,64,229,52,22,65,108,191,94,172,64,181,51,20,65,108,67,168,165,64,225,6,18,65,108,149,43,159,64,206,175,15,65,108,220,236,152,64,250,47,13,65,108,24,240,146,64,255,136,10,65,108,29,57,141,64,144,188,7,
65,108,147,203,135,64,119,204,4,65,108,242,170,130,64,149,186,1,65,108,4,181,123,64,192,17,253,64,108,180,186,114,64,202,114,246,64,108,176,108,106,64,130,156,239,64,108,72,208,98,64,74,147,232,64,108,92,234,91,64,161,91,225,64,108,86,191,85,64,38,250,
217,64,108,40,83,80,64,146,115,210,64,108,76,169,75,64,182,204,202,64,108,184,196,71,64,120,10,195,64,108,240,167,68,64,204,49,187,64,108,240,84,66,64,187,71,179,64,108,52,205,64,64,83,81,171,64,108,182,17,64,64,173,83,163,64,108,0,0,64,64,0,0,160,64,
108,0,0,64,64,0,0,160,64,108,0,0,64,64,0,0,160,64,108,96,102,64,64,216,0,152,64,108,68,153,65,64,207,6,144,64,108,226,151,67,64,254,22,136,64,108,246,96,70,64,121,54,128,64,108,182,242,73,64,152,212,112,64,108,220,74,78,64,229,110,97,64,108,160,102,83,
64,181,69,82,64,108,188,66,89,64,188,98,67,64,108,112,219,95,64,127,207,52,64,108,130,44,103,64,82,149,38,64,108,72,49,111,64,80,189,24,64,108,156,228,119,64,85,80,11,64,108,120,160,128,64,240,173,252,63,108,34,160,133,64,8,179,227,63,108,27,238,138,
64,246,191,203,63,108,252,134,144,64,8,228,180,63,108,48,103,150,64,220,45,159,63,108,248,138,156,64,94,171,138,63,108,98,238,162,64,80,211,110,63,108,90,141,169,64,32,234,74,63,108,162,99,176,64,32,178,41,63,108,220,108,183,64,144,64,11,63,108,133,164,
190,64,224,81,223,62,108,0,6,198,64,192,249,173,62,108,149,140,205,64,112,152,130,62,108,114,51,213,64,64,147,58,62,108,177,245,220,64,0,149,248,61,108,93,206,228,64,64,252,148,61,108,111,184,236,64,128,57,21,61,108,215,174,244,64,0,44,77,60,108,125,
172,252,64,0,160,141,58,108,1,0,0,65,0,0,0,0,108,0,0,0,65,0,0,0,0,108,0,0,0,65,0,0,0,0,108,147,255,3,65,0,192,204,59,108,151,252,7,65,0,161,204,60,108,126,244,11,65,0,248,101,61,108,191,228,15,65,64,30,204,61,108,213,202,19,65,32,43,31,62,108,65,164,
23,65,96,173,100,62,108,140,110,27,65,176,52,155,62,108,74,39,31,65,128,21,202,62,108,24,204,34,65,0,219,254,62,108,163,90,38,65,192,177,28,63,108,163,208,41,65,200,196,60,63,108,225,43,45,65,8,146,95,63,108,56,106,48,65,164,129,130,63,108,148,137,51,
65,70,128,150,63,108,246,135,54,65,28,184,171,63,108,116,99,57,65,152,27,194,63,108,58,26,60,65,96,156,217,63,108,138,170,62,65,112,43,242,63,108,192,18,65,65,136,220,5,64,108,84,81,67,65,113,26,19,64,108,212,100,69,65,252,198,32,64,108,238,75,71,65,
105,217,46,64,108,104,5,73,65,181,72,61,64,108,41,144,74,65,166,11,76,64,108,52,235,75,65,200,24,91,64,108,172,21,77,65,124,102,106,64,108,208,14,78,65,244,234,121,64,108,2,214,78,65,35,206,132,64,108,195,106,79,65,50,184,140,64,108,178,204,79,65,151,
174,148,64,108,146,251,79,65,58,172,156,64,108,0,0,80,65,0,0,160,64,108,0,0,80,65,0,0,160,64,99,101,0,0 };
const uint8 closedFolder[] = { 110,109,0,0,0,65,0,0,0,0,108,0,0,0,65,0,0,128,63,108,0,0,0,65,0,0,0,64,108,0,0,0,0,0,0,0,64,108,0,0,0,0,0,0,96,65,108,0,0,144,65,0,0,96,65,108,0,0,144,65,0,0,0,64,108,0,0,128,65,0,0,0,64,108,0,0,128,65,0,0,0,0,108,0,0,0,65,0,0,0,0,99,101,0,0 };
const uint8 exporter[] = { 110,109,0,120,99,65,0,128,94,63,108,0,40,88,65,0,192,201,63,108,0,232,42,65,0,240,140,64,108,0,80,251,64,0,192,201,63,108,0,128,72,63,0,88,10,65,108,0,192,190,63,0,168,21,65,108,0,32,103,64,0,152,55,65,108,0,128,67,63,0,40,101,65,108,0,0,104,61,0,120,
112,65,108,0,64,188,63,0,140,131,65,108,0,96,11,64,0,200,123,65,108,0,208,160,64,0,56,78,65,108,0,80,251,64,0,128,123,65,108,0,208,110,65,0,88,10,65,108,0,136,65,65,0,48,186,64,108,0,200,110,65,0,96,63,64,108,0,24,122,65,0,32,18,64,108,0,120,99,65,0,
128,94,63,99,109,0,80,251,64,0,240,140,64,108,0,72,20,65,0,48,186,64,108,0,248,19,65,0,208,186,64,108,0,152,42,65,0,16,232,64,108,0,232,42,65,0,112,231,64,108,0,144,65,65,0,88,10,65,108,0,80,251,64,0,56,78,65,108,0,16,206,64,0,152,55,65,108,0,208,160,
64,0,248,32,65,108,0,32,103,64,0,88,10,65,108,0,80,251,64,0,240,140,64,99,101,0,0 };
const uint8 fileExplorer[] = { 110,109,0,0,0,65,0,0,0,0,108,0,0,0,65,0,0,192,64,108,0,0,32,65,0,0,192,64,108,0,0,32,65,0,0,208,64,108,0,0,32,65,0,0,0,65,108,0,0,0,64,0,0,0,65,108,0,0,0,64,0,0,64,65,108,0,0,0,0,0,0,64,65,108,0,0,0,0,0,0,144,65,108,0,0,192,64,0,0,144,65,108,0,0,192,
64,0,0,64,65,108,0,0,128,64,0,0,64,65,108,0,0,128,64,0,0,32,65,108,0,0,32,65,0,0,32,65,108,0,0,32,65,0,0,56,65,108,0,0,32,65,0,0,64,65,108,0,0,0,65,0,0,64,65,108,0,0,0,65,0,0,144,65,108,0,0,96,65,0,0,144,65,108,0,0,96,65,0,0,64,65,108,0,0,64,65,0,0,64,
65,108,0,0,64,65,0,0,56,65,108,0,0,64,65,0,0,32,65,108,0,0,144,65,0,0,32,65,108,0,0,144,65,0,0,56,65,108,0,0,144,65,0,0,64,65,108,0,0,128,65,0,0,64,65,108,0,0,128,65,0,0,144,65,108,0,0,176,65,0,0,144,65,108,0,0,176,65,0,0,64,65,108,0,0,160,65,0,0,64,
65,108,0,0,160,65,0,0,56,65,108,0,0,160,65,0,0,0,65,108,0,0,64,65,0,0,0,65,108,0,0,64,65,0,0,208,64,108,0,0,64,65,0,0,192,64,108,0,0,96,65,0,0,192,64,108,0,0,96,65,0,0,0,0,108,0,0,0,65,0,0,0,0,99,101,0,0 };
const uint8 file[] = { 110,109,0,0,0,0,0,0,0,0,108,0,0,0,0,0,0,144,65,108,0,0,96,65,0,0,144,65,108,0,0,96,65,0,0,136,65,108,0,0,96,65,0,0,0,65,108,0,0,96,65,0,112,212,64,108,0,128,7,65,0,0,0,0,108,0,0,0,65,0,0,0,0,108,0,0,0,0,0,0,0,0,99,109,0,0,0,64,0,0,0,64,108,0,176,234,
64,0,0,0,64,108,0,0,192,64,0,0,192,64,108,0,0,64,65,0,0,240,64,108,0,0,64,65,0,0,128,65,108,0,0,0,64,0,0,128,65,108,0,0,0,64,0,0,0,64,99,101,0,0 };
const uint8 modules[] = { 110,109,193,202,222,64,80,50,21,64,108,0,0,48,65,0,0,0,0,108,160,154,112,65,80,50,21,64,108,0,0,48,65,80,50,149,64,108,193,202,222,64,80,50,21,64,99,109,0,0,192,64,251,220,127,64,108,160,154,32,65,165,135,202,64,108,160,154,32,65,250,220,47,65,108,0,
0,192,64,102,144,10,65,108,0,0,192,64,251,220,127,64,99,109,0,0,128,65,251,220,127,64,108,0,0,128,65,103,144,10,65,108,96,101,63,65,251,220,47,65,108,96,101,63,65,166,135,202,64,108,0,0,128,65,251,220,127,64,99,109,96,101,79,65,148,76,69,65,108,0,0,136,
65,0,0,32,65,108,80,77,168,65,148,76,69,65,108,0,0,136,65,40,153,106,65,108,96,101,79,65,148,76,69,65,99,109,0,0,64,65,63,247,95,65,108,80,77,128,65,233,161,130,65,108,80,77,128,65,125,238,167,65,108,0,0,64,65,51,72,149,65,108,0,0,64,65,63,247,95,65,
99,109,0,0,176,65,63,247,95,65,108,0,0,176,65,51,72,149,65,108,176,178,143,65,125,238,167,65,108,176,178,143,65,233,161,130,65,108,0,0,176,65,63,247,95,65,99,109,12,86,118,63,148,76,69,65,108,0,0,160,64,0,0,32,65,108,159,154,16,65,148,76,69,65,108,0,
0,160,64,40,153,106,65,108,12,86,118,63,148,76,69,65,99,109,0,0,0,0,63,247,95,65,108,62,53,129,64,233,161,130,65,108,62,53,129,64,125,238,167,65,108,0,0,0,0,51,72,149,65,108,0,0,0,0,63,247,95,65,99,109,0,0,32,65,63,247,95,65,108,0,0,32,65,51,72,149,65,
108,193,202,190,64,125,238,167,65,108,193,202,190,64,233,161,130,65,108,0,0,32,65,63,247,95,65,99,101,0,0 };
const uint8 openFolder[] = { 110,109,0,0,32,65,0,0,0,0,108,0,0,32,65,0,0,0,64,108,0,0,0,64,0,0,0,64,108,0,0,0,64,0,0,192,64,108,0,0,0,0,0,0,192,64,108,0,0,0,64,0,0,128,65,108,0,0,152,65,0,0,128,65,108,0,0,160,65,0,0,128,65,108,0,0,160,65,0,0,112,65,108,0,0,160,65,0,0,0,64,108,0,
0,144,65,0,0,0,64,108,0,0,144,65,0,0,0,0,108,0,0,32,65,0,0,0,0,99,109,0,0,64,65,0,0,0,64,108,0,0,128,65,0,0,0,64,108,0,0,128,65,0,0,128,64,108,0,0,144,65,0,0,128,64,108,0,0,144,65,0,0,48,65,108,0,0,136,65,0,0,192,64,108,0,0,128,64,0,0,192,64,108,0,0,
128,64,0,0,128,64,108,0,0,64,65,0,0,128,64,108,0,0,64,65,0,0,0,64,99,101,0,0 };
const uint8 settings[] = { 110,109,202,111,210,64,243,226,61,64,108,0,0,224,64,0,0,0,0,108,0,0,48,65,0,0,0,0,108,27,200,54,65,243,226,61,64,98,91,248,63,65,174,170,76,64,95,130,72,65,231,138,96,64,46,46,80,65,180,163,120,64,108,42,181,124,65,20,38,49,64,108,149,90,142,65,246,108,
199,64,108,68,249,118,65,2,85,1,65,98,112,166,119,65,201,31,6,65,0,0,120,65,111,5,11,65,0,0,120,65,0,0,16,65,98,0,0,120,65,145,250,20,65,108,166,119,65,55,224,25,65,72,249,118,65,254,170,30,65,108,151,90,142,65,133,73,60,65,108,46,181,124,65,123,182,
115,65,108,50,46,80,65,18,215,97,65,98,99,130,72,65,70,221,103,65,96,248,63,65,83,213,108,65,32,200,54,65,66,135,112,65,108,0,0,48,65,0,0,144,65,108,0,0,224,64,0,0,144,65,108,202,111,210,64,67,135,112,65,98,74,15,192,64,84,213,108,65,65,251,174,64,70,
221,103,65,164,163,159,64,19,215,97,65,108,92,43,13,64,123,182,115,65,108,187,181,82,62,133,73,60,65,108,244,26,36,64,254,170,30,65,98,64,102,33,64,55,224,25,65,0,0,32,64,145,250,20,65,0,0,32,64,0,0,16,65,98,0,0,32,64,111,5,11,65,64,102,33,64,201,31,
6,65,244,26,36,64,2,85,1,65,108,187,181,82,62,246,108,199,64,108,92,43,13,64,20,38,49,64,108,164,163,159,64,180,163,120,64,98,65,251,174,64,231,138,96,64,74,15,192,64,175,170,76,64,202,111,210,64,243,226,61,64,99,109,0,0,16,65,0,0,64,65,98,121,130,42,
65,0,0,64,65,0,0,64,65,121,130,42,65,0,0,64,65,0,0,16,65,98,0,0,64,65,13,251,234,64,121,130,42,65,0,0,192,64,0,0,16,65,0,0,192,64,98,13,251,234,64,0,0,192,64,0,0,192,64,13,251,234,64,0,0,192,64,0,0,16,65,98,0,0,192,64,121,130,42,65,13,251,234,64,0,0,
64,65,0,0,16,65,0,0,64,65,99,101,0,0 };
const uint8 singleModule[] = { 110,109,165,48,137,63,179,12,91,64,108,0,0,224,64,0,0,0,0,108,235,217,78,65,179,12,91,64,108,0,0,224,64,176,12,219,64,108,165,48,137,63,179,12,91,64,99,109,51,10,147,61,80,243,164,64,108,0,0,192,64,211,60,9,65,108,0,0,192,64,45,195,118,65,108,51,10,147,
61,0,0,64,65,108,51,10,147,61,80,243,164,64,99,109,235,217,94,65,80,243,164,64,108,235,217,94,65,0,0,64,65,108,0,0,0,65,45,195,118,65,108,0,0,0,65,211,60,9,65,108,235,217,94,65,80,243,164,64,99,101,0,0 };
const uint8 plus[] = { 110,109,0,128,223,64,0,0,96,188,108,0,128,223,64,64,0,96,188,108,189,230,221,64,128,185,62,188,108,210,78,220,64,128,42,233,187,108,68,185,218,64,0,32,225,184,108,23,39,217,64,0,118,25,60,108,75,153,215,64,32,88,174,60,108,223,16,214,64,192,219,17,61,
108,206,142,212,64,48,71,86,61,108,16,20,211,64,64,33,146,61,108,151,161,209,64,232,205,189,61,108,79,56,208,64,152,13,238,61,108,32,217,206,64,188,96,17,62,108,235,132,205,64,232,227,45,62,108,137,60,204,64,16,126,76,62,108,204,0,203,64,160,27,109,62,
108,127,210,201,64,220,211,135,62,108,98,178,200,64,30,6,154,62,108,48,161,199,64,242,24,173,62,108,148,159,198,64,38,0,193,62,108,54,174,197,64,248,174,213,62,108,176,205,196,64,52,24,235,62,108,144,254,195,64,14,151,0,63,108,92,65,195,64,76,241,11,
63,108,140,150,194,64,141,147,23,63,108,142,254,193,64,98,118,35,63,108,196,121,193,64,47,146,47,63,108,129,8,193,64,52,223,59,63,108,15,171,192,64,146,85,72,63,108,169,97,192,64,81,237,84,63,108,127,44,192,64,97,158,97,63,108,178,11,192,64,164,96,110,
63,108,87,255,191,64,238,43,123,63,108,0,0,192,64,0,0,128,63,108,0,0,192,64,0,0,128,63,108,0,0,192,64,0,0,192,64,108,0,0,128,63,0,0,192,64,108,0,0,128,63,0,0,192,64,108,104,51,115,63,114,4,192,64,108,176,108,102,63,92,29,192,64,108,4,180,89,63,172,74,
192,64,108,136,17,77,63,71,140,192,64,108,82,141,64,63,1,226,192,64,108,100,47,52,63,165,75,193,64,108,167,255,39,63,238,200,193,64,108,232,5,28,63,140,89,194,64,108,210,73,16,63,36,253,194,64,108,229,210,4,63,76,179,195,64,108,240,80,243,62,143,123,
196,64,108,96,163,221,62,110,85,197,64,108,248,170,200,62,93,64,198,64,108,38,117,180,62,197,59,199,64,108,214,14,161,62,7,71,200,64,108,112,132,142,62,118,97,201,64,108,168,195,121,62,95,138,202,64,108,148,100,88,62,3,193,203,64,108,0,1,57,62,155,4,
205,64,108,0,173,27,62,89,84,206,64,108,88,123,0,62,101,175,207,64,108,224,250,206,61,226,20,209,64,108,136,134,161,61,234,131,210,64,108,128,109,113,61,147,251,211,64,108,64,75,41,61,237,122,213,64,108,32,169,213,60,2,1,215,64,108,0,197,88,60,216,140,
216,64,108,0,51,56,59,115,29,218,64,108,128,212,168,187,210,177,219,64,108,128,75,46,188,242,72,221,64,108,64,94,95,188,206,225,222,64,108,128,130,103,188,98,123,224,64,108,128,179,70,188,167,20,226,64,108,0,12,250,187,151,172,227,64,108,0,148,42,186,
46,66,229,64,108,128,25,16,60,102,212,230,64,108,192,111,169,60,65,98,232,64,108,240,74,15,61,190,234,233,64,108,48,154,83,61,226,108,235,64,108,224,188,144,61,183,231,236,64,108,0,92,188,61,74,90,238,64,108,136,142,236,61,173,195,239,64,108,200,154,
16,62,251,34,241,64,108,188,23,45,62,82,119,242,64,108,228,171,75,62,215,191,243,64,108,172,67,108,62,186,251,244,64,108,30,101,135,62,47,42,246,64,108,188,148,153,62,118,74,247,64,108,18,165,172,62,213,91,248,64,108,232,137,192,62,159,93,249,64,108,
134,54,213,62,45,79,250,64,108,176,157,234,62,230,47,251,64,108,218,88,0,63,57,255,251,64,108,58,178,11,63,163,188,252,64,108,180,83,23,63,169,103,253,64,108,216,53,35,63,222,255,253,64,108,9,81,47,63,225,132,254,64,108,138,157,59,63,94,246,254,64,108,
123,19,72,63,10,84,255,64,108,228,170,84,63,170,157,255,64,108,181,91,97,63,16,211,255,64,108,209,29,110,63,25,244,255,64,108,13,233,122,63,88,0,0,65,108,254,255,127,63,0,0,0,65,108,0,0,128,63,0,0,0,65,108,0,0,192,64,0,0,0,65,108,0,0,192,64,0,0,80,65,
108,0,0,192,64,0,0,80,65,108,114,4,192,64,202,204,80,65,108,92,29,192,64,53,153,81,65,108,172,74,192,64,192,100,82,65,108,70,140,192,64,232,46,83,65,108,1,226,192,64,43,247,83,65,108,164,75,193,64,10,189,84,65,108,238,200,193,64,6,128,85,65,108,140,89,
194,64,161,63,86,65,108,36,253,194,64,99,251,86,65,108,75,179,195,64,210,178,87,65,108,142,123,196,64,120,101,88,65,108,109,85,197,64,229,18,89,65,108,92,64,198,64,168,186,89,65,108,196,59,199,64,87,92,90,65,108,6,71,200,64,137,247,90,65,108,117,97,201,
64,220,139,91,65,108,94,138,202,64,241,24,92,65,108,2,193,203,64,109,158,92,65,108,154,4,205,64,252,27,93,65,108,87,84,206,64,76,145,93,65,108,99,175,207,64,18,254,93,65,108,224,20,209,64,10,98,94,65,108,232,131,210,64,243,188,94,65,108,145,251,211,64,
146,14,95,65,108,235,122,213,64,181,86,95,65,108,0,1,215,64,43,149,95,65,108,214,140,216,64,207,201,95,65,108,113,29,218,64,125,244,95,65,108,208,177,219,64,27,21,96,65,108,240,72,221,64,147,43,96,65,108,204,225,222,64,216,55,96,65,108,96,123,224,64,
225,57,96,65,108,165,20,226,64,173,49,96,65,108,149,172,227,64,66,31,96,65,108,43,66,229,64,171,2,96,65,108,100,212,230,64,250,219,95,65,108,63,98,232,64,73,171,95,65,108,187,234,233,64,182,112,95,65,108,224,108,235,64,102,44,95,65,108,181,231,236,64,
135,222,94,65,108,72,90,238,64,73,135,94,65,108,172,195,239,64,228,38,94,65,108,249,34,241,64,150,189,93,65,108,80,119,242,64,162,75,93,65,108,214,191,243,64,81,209,92,65,108,184,251,244,64,242,78,92,65,108,46,42,246,64,216,196,91,65,108,116,74,247,64,
91,51,91,65,108,212,91,248,64,217,154,90,65,108,158,93,249,64,178,251,89,65,108,44,79,250,64,77,86,89,65,108,230,47,251,64,19,171,88,65,108,57,255,251,64,115,250,87,65,108,163,188,252,64,220,68,87,65,108,169,103,253,64,197,138,86,65,108,223,255,253,64,
162,204,85,65,108,226,132,254,64,239,10,85,65,108,94,246,254,64,39,70,84,65,108,10,84,255,64,199,126,83,65,108,171,157,255,64,80,181,82,65,108,16,211,255,64,67,234,81,65,108,25,244,255,64,33,30,81,65,108,88,0,0,65,109,81,80,65,108,0,0,0,65,0,0,80,65,
108,0,0,0,65,0,0,80,65,108,0,0,0,65,0,0,0,65,108,0,0,80,65,0,0,0,65,108,0,0,80,65,0,0,0,65,108,202,204,80,65,142,251,255,64,108,53,153,81,65,164,226,255,64,108,192,100,82,65,84,181,255,64,108,232,46,83,65,185,115,255,64,108,43,247,83,65,255,29,255,64,
108,10,189,84,65,92,180,254,64,108,6,128,85,65,18,55,254,64,108,162,63,86,65,116,166,253,64,108,99,251,86,65,220,2,253,64,108,210,178,87,65,181,76,252,64,108,120,101,88,65,114,132,251,64,108,229,18,89,65,147,170,250,64,108,168,186,89,65,164,191,249,64,
108,87,92,90,65,60,196,248,64,108,137,247,90,65,250,184,247,64,108,220,139,91,65,139,158,246,64,108,241,24,92,65,162,117,245,64,108,109,158,92,65,254,62,244,64,108,252,27,93,65,102,251,242,64,108,76,145,93,65,169,171,241,64,108,18,254,93,65,157,80,240,
64,108,10,98,94,65,32,235,238,64,108,243,188,94,65,24,124,237,64,108,146,14,95,65,111,4,236,64,108,181,86,95,65,21,133,234,64,108,43,149,95,65,0,255,232,64,108,207,201,95,65,42,115,231,64,108,125,244,95,65,143,226,229,64,108,27,21,96,65,49,78,228,64,
108,147,43,96,65,17,183,226,64,108,216,55,96,65,52,30,225,64,108,225,57,96,65,160,132,223,64,108,173,49,96,65,91,235,221,64,108,66,31,96,65,107,83,220,64,108,171,2,96,65,213,189,218,64,108,250,219,95,65,156,43,217,64,108,73,171,95,65,194,157,215,64,108,
182,112,95,65,69,21,214,64,108,102,44,95,65,32,147,212,64,108,135,222,94,65,75,24,211,64,108,73,135,94,65,184,165,209,64,108,228,38,94,65,84,60,208,64,108,150,189,93,65,7,221,206,64,108,162,75,93,65,176,136,205,64,108,81,209,92,65,42,64,204,64,108,242,
78,92,65,72,4,203,64,108,216,196,91,65,210,213,201,64,108,91,51,91,65,139,181,200,64,108,216,154,90,65,44,164,199,64,108,178,251,89,65,98,162,198,64,108,77,86,89,65,212,176,197,64,108,19,171,88,65,27,208,196,64,108,115,250,87,65,199,0,196,64,108,221,
68,87,65,94,67,195,64,108,197,138,86,65,88,152,194,64,108,163,204,85,65,34,0,194,64,108,240,10,85,65,31,123,193,64,108,40,70,84,65,163,9,193,64,108,201,126,83,65,246,171,192,64,108,82,181,82,65,86,98,192,64,108,69,234,81,65,240,44,192,64,108,35,30,81,
65,231,11,192,64,108,111,81,80,65,81,255,191,64,108,0,0,80,65,0,0,192,64,108,0,0,80,65,0,0,192,64,108,0,0,0,65,0,0,192,64,108,0,0,0,65,0,0,128,63,108,0,0,0,65,0,0,128,63,108,94,251,255,64,110,51,115,63,108,70,226,255,64,205,108,102,63,108,199,180,255,
64,76,180,89,63,108,254,114,255,64,13,18,77,63,108,21,29,255,64,39,142,64,63,108,68,179,254,64,154,48,52,63,108,206,53,254,64,82,1,40,63,108,4,165,253,64,26,8,28,63,108,65,1,253,64,155,76,16,63,108,239,74,252,64,87,214,4,63,108,131,130,251,64,70,89,243,
62,108,124,168,250,64,72,173,221,62,108,103,189,249,64,144,182,200,62,108,217,193,248,64,140,130,180,62,108,115,182,247,64,38,30,161,62,108,226,155,246,64,200,149,142,62,108,217,114,245,64,160,234,121,62,108,22,60,244,64,4,144,88,62,108,97,248,242,64,
24,49,57,62,108,136,168,241,64,236,225,27,62,108,99,77,240,64,64,181,0,62,108,207,231,238,64,240,120,207,61,108,178,120,237,64,40,15,162,61,108,246,0,236,64,96,148,114,61,108,140,129,234,64,32,136,42,61,108,104,251,232,64,160,79,216,60,108,134,111,231,
64,64,109,94,60,108,225,222,229,64,0,67,80,59,108,123,74,228,64,128,17,156,187,108,85,179,226,64,128,140,39,188,108,118,26,225,64,192,64,88,188,108,225,128,223,64,0,7,96,188,108,0,128,223,64,0,0,96,188,108,0,128,223,64,0,0,96,188,99,101,0,0 };
const uint8 android[] = { 110,109,31,179,128,65,235,31,97,65,98,31,179,128,65,216,190,108,65,127,102,133,65,162,42,118,65,26,51,139,65,162,42,118,65,108,26,51,139,65,162,42,118,65,98,153,255,144,65,162,42,118,65,21,179,149,65,216,190,108,65,21,179,149,65,235,31,97,65,108,21,179,
149,65,134,3,12,65,98,21,179,149,65,153,100,0,65,152,255,144,65,158,241,237,64,26,51,139,65,158,241,237,64,108,26,51,139,65,158,241,237,64,98,128,102,133,65,158,241,237,64,31,179,128,65,153,100,0,65,31,179,128,65,134,3,12,65,108,31,179,128,65,234,31,
97,65,99,109,121,61,100,64,184,62,239,64,108,121,61,100,64,168,171,136,65,98,121,61,100,64,44,60,141,65,127,228,128,64,157,239,144,65,141,30,147,64,157,239,144,65,108,175,38,186,64,157,239,144,65,108,175,38,186,64,221,149,168,65,98,175,38,186,64,112,
101,174,65,50,244,204,64,57,27,179,65,156,38,228,64,57,27,179,65,98,6,89,251,64,57,27,179,65,125,19,7,65,112,101,174,65,125,19,7,65,221,149,168,65,108,125,19,7,65,157,239,144,65,108,220,76,39,65,157,239,144,65,108,220,76,39,65,221,149,168,65,98,220,76,
39,65,112,101,174,65,101,179,48,65,57,27,179,65,211,76,60,65,57,27,179,65,98,65,230,71,65,57,27,179,65,202,76,81,65,112,101,174,65,202,76,81,65,221,149,168,65,108,202,76,81,65,157,239,144,65,108,218,208,100,65,157,239,144,65,98,225,237,109,65,157,239,
144,65,52,81,117,65,185,60,141,65,52,81,117,65,168,171,136,65,108,52,81,117,65,184,62,239,64,108,124,61,100,64,184,62,239,64,99,109,106,232,51,64,234,31,97,65,98,106,232,51,64,215,190,108,65,130,76,14,64,161,42,118,65,91,207,191,63,161,42,118,65,108,
91,207,191,63,161,42,118,65,98,235,14,70,63,161,42,118,65,48,125,62,62,215,190,108,65,48,125,62,62,234,31,97,65,108,48,125,62,62,134,3,12,65,98,48,125,62,62,153,100,0,65,235,14,70,63,158,241,237,64,91,207,191,63,158,241,237,64,108,91,207,191,63,158,241,
237,64,98,130,76,14,64,158,241,237,64,106,232,51,64,153,100,0,65,106,232,51,64,134,3,12,65,108,106,232,51,64,234,31,97,65,99,109,150,130,62,65,58,171,159,64,98,172,194,56,65,58,171,159,64,87,25,52,65,88,83,150,64,87,25,52,65,221,203,138,64,98,87,25,52,
65,226,135,126,64,172,194,56,65,30,216,107,64,150,130,62,65,30,216,107,64,98,10,68,68,65,30,216,107,64,239,236,72,65,168,137,126,64,239,236,72,65,221,203,138,64,98,239,236,72,65,230,82,150,64,153,67,68,65,58,171,159,64,150,130,62,65,58,171,159,64,109,
135,187,223,64,58,171,159,64,98,128,57,212,64,58,171,159,64,100,230,202,64,88,83,150,64,100,230,202,64,221,203,138,64,98,100,230,202,64,167,137,126,64,45,56,212,64,30,216,107,64,136,187,223,64,30,216,107,64,98,90,59,235,64,30,216,107,64,148,141,244,64,
226,135,126,64,148,141,244,64,221,203,138,64,98,5,142,244,64,230,82,150,64,90,59,235,64,58,171,159,64,136,187,223,64,58,171,159,64,109,208,208,67,65,188,224,31,64,108,196,50,85,65,248,218,106,63,98,0,59,86,65,53,205,82,63,56,249,85,65,66,58,51,63,195,
159,84,65,51,76,36,63,98,192,70,83,65,100,115,21,63,214,87,81,65,146,202,28,63,152,81,80,65,106,223,52,63,108,206,64,62,65,202,79,22,64,98,3,89,50,65,182,131,3,64,149,32,37,65,39,20,242,63,99,49,23,65,39,20,242,63,98,48,66,9,65,39,20,242,63,195,17,248,
64,15,129,3,64,158,66,224,64,202,79,22,64,108,100,34,188,64,224,219,52,63,98,43,16,186,64,28,206,28,63,32,52,182,64,219,111,21,63,164,129,179,64,174,72,36,63,98,40,207,176,64,31,44,51,63,9,76,176,64,156,194,82,63,127,92,178,64,115,215,106,63,108,123,
35,213,64,219,223,31,64,98,38,216,157,64,148,108,83,64,182,34,110,64,196,176,154,64,1,65,100,64,77,218,211,64,108,223,79,117,65,77,218,211,64,98,167,217,114,65,196,176,154,64,10,118,95,65,118,109,83,64,207,208,67,65,189,224,31,64,101,0,0 };
const uint8 codeBlocks[] = { 110,109,0,0,0,0,0,0,0,0,108,0,0,0,0,0,208,235,64,108,0,192,134,64,0,152,23,65,108,0,152,23,65,0,152,23,65,108,0,152,23,65,0,192,134,64,108,0,208,235,64,0,0,0,0,108,0,0,0,0,0,0,0,0,99,109,0,24,74,65,0,0,0,0,108,0,104,40,65,0,192,134,64,108,0,104,40,65,
0,152,23,65,108,255,159,124,65,0,152,23,65,108,0,0,160,65,0,208,235,64,108,0,0,160,65,0,0,0,0,108,0,24,74,65,0,0,0,0,99,109,0,192,134,64,0,104,40,65,108,0,0,0,0,0,24,74,65,108,0,0,0,0,0,0,160,65,108,0,208,235,64,0,0,160,65,108,0,152,23,65,255,159,124,
65,108,0,152,23,65,0,104,40,65,108,0,192,134,64,0,104,40,65,99,109,0,104,40,65,0,104,40,65,108,0,104,40,65,255,159,124,65,108,0,24,74,65,0,0,160,65,108,0,0,160,65,0,0,160,65,108,0,0,160,65,0,24,74,65,108,255,159,124,65,0,104,40,65,108,0,104,40,65,0,104,
40,65,99,101,0,0 };
const uint8 linux[] = { 110,109,0,0,124,66,174,71,130,66,108,0,0,124,66,174,71,130,66,108,162,178,123,66,87,5,130,66,108,186,94,123,66,5,197,129,66,108,128,4,123,66,225,134,129,66,108,45,164,122,66,17,75,129,66,108,254,61,122,66,189,17,129,66,108,52,210,121,66,9,219,128,66,
108,22,97,121,66,24,167,128,66,108,234,234,120,66,11,118,128,66,108,143,194,120,66,102,102,128,66,108,143,194,120,66,102,102,128,66,108,143,194,120,66,102,102,128,66,108,167,246,119,66,12,20,128,66,108,198,34,119,66,200,141,127,66,108,114,71,118,66,65,
254,126,66,108,245,40,118,66,132,235,126,66,108,245,40,118,66,132,235,126,66,108,112,61,117,66,234,81,126,66,108,111,61,117,66,234,81,126,66,108,17,6,115,66,5,193,124,66,108,114,227,112,66,69,20,123,66,108,162,112,111,66,9,215,121,66,108,163,112,111,
66,9,215,121,66,108,164,112,111,66,10,215,121,66,108,204,182,109,66,55,99,120,66,108,23,16,108,66,198,217,118,66,108,148,125,106,66,178,59,117,66,108,113,61,106,66,194,245,116,66,108,112,61,106,66,193,245,116,66,108,112,61,106,66,193,245,116,66,108,32,
222,105,66,15,140,116,66,108,56,132,105,66,187,29,116,66,108,239,47,105,66,13,171,115,66,108,125,225,104,66,76,52,115,66,108,20,153,104,66,198,185,114,66,108,225,86,104,66,201,59,114,66,108,15,27,104,66,165,186,113,66,108,197,229,103,66,173,54,113,66,
108,37,183,103,66,54,176,112,66,108,76,143,103,66,149,39,112,66,108,31,133,103,66,255,255,111,66,108,31,133,103,66,0,0,112,66,108,31,133,103,66,1,0,112,66,108,55,95,103,66,33,237,110,66,108,24,71,103,66,180,216,109,66,108,113,61,103,66,133,235,108,66,
108,113,61,103,66,133,235,108,66,108,113,61,103,66,225,122,107,66,108,113,61,103,66,225,122,107,66,108,153,25,103,66,15,82,106,66,108,247,230,102,66,103,43,105,66,108,171,165,102,66,165,7,104,66,108,223,85,102,66,131,231,102,66,108,198,247,101,66,187,
203,101,66,108,144,194,101,66,112,61,101,66,108,144,194,101,66,112,61,101,66,108,144,194,101,66,112,61,101,66,108,66,119,101,66,161,143,100,66,108,93,35,101,66,205,229,99,66,108,21,199,100,66,97,64,99,66,108,166,98,100,66,198,159,98,66,108,81,246,99,
66,100,4,98,66,108,90,130,99,66,158,110,97,66,108,12,7,99,66,211,222,96,66,108,1,0,99,66,10,215,96,66,108,1,0,99,66,10,215,96,66,108,1,0,99,66,10,215,96,66,108,182,121,98,66,28,94,96,66,108,138,237,97,66,11,236,95,66,108,216,91,97,66,32,129,95,66,108,
253,196,96,66,159,29,95,66,108,89,41,96,66,200,193,94,66,108,79,137,95,66,214,109,94,66,108,71,229,94,66,255,33,94,66,108,169,61,94,66,114,222,93,66,108,224,146,93,66,92,163,93,66,108,237,81,93,66,92,143,93,66,108,237,81,93,66,92,143,93,66,108,206,204,
92,66,92,143,93,66,108,206,204,92,66,92,143,93,66,108,206,204,92,66,92,143,93,66,108,124,20,93,66,10,215,92,66,108,124,20,93,66,10,215,92,66,108,104,246,93,66,191,108,91,66,108,240,197,94,66,157,247,89,66,108,144,130,95,66,148,120,88,66,108,207,43,96,
66,151,240,86,66,108,64,193,96,66,162,96,85,66,108,132,66,97,66,182,201,83,66,108,72,175,97,66,213,44,82,66,108,71,7,98,66,9,139,80,66,108,62,10,98,66,225,122,80,66,108,63,10,98,66,225,122,80,66,108,63,10,98,66,225,122,80,66,108,31,110,98,66,238,111,
77,66,108,240,170,98,66,246,96,74,66,108,141,192,98,66,239,79,71,66,108,231,174,98,66,207,62,68,66,108,8,118,98,66,139,47,65,66,108,22,22,98,66,26,36,62,66,108,94,143,97,66,184,30,59,66,108,94,143,97,66,184,30,59,66,108,94,143,97,66,184,30,59,66,108,
246,32,96,66,254,27,52,66,108,81,89,94,66,212,45,45,66,108,146,57,92,66,166,88,38,66,108,21,195,89,66,213,160,31,66,108,94,143,89,66,184,30,31,66,108,94,143,89,66,184,30,31,66,108,94,143,89,66,184,30,31,66,108,240,13,88,66,120,66,27,66,108,152,91,86,
66,184,122,23,66,108,111,121,84,66,226,201,19,66,108,166,104,82,66,83,50,16,66,108,145,42,80,66,88,182,12,66,108,145,194,79,66,184,30,12,66,108,145,194,79,66,184,30,12,66,98,145,194,75,66,225,122,6,66,227,122,70,66,143,194,1,66,227,122,66,66,112,61,248,
65,98,247,40,65,66,225,122,244,65,2,0,64,66,112,61,240,65,145,194,62,66,204,204,236,65,98,125,20,61,66,143,194,229,65,104,102,59,66,204,204,222,65,206,204,57,66,20,174,215,65,98,52,51,55,66,143,194,203,65,32,133,52,66,20,174,191,65,104,102,49,66,245,
40,180,65,108,237,81,48,66,235,81,176,65,98,135,235,47,66,235,81,164,65,176,71,47,66,235,81,152,65,196,245,46,66,102,102,140,65,98,42,92,46,66,204,204,108,65,196,245,46,66,224,122,64,65,176,71,44,66,112,61,22,65,108,176,71,44,66,112,61,22,65,108,205,
151,43,66,90,43,12,65,108,236,199,42,66,166,63,2,65,108,146,216,41,66,91,1,241,64,108,88,202,40,66,90,233,221,64,108,235,157,39,66,128,67,203,64,108,11,84,38,66,190,27,185,64,108,0,0,38,66,205,204,180,64,108,0,0,38,66,205,204,180,64,108,0,0,38,66,205,
204,180,64,108,29,150,36,66,8,152,163,64,108,42,17,35,66,117,249,146,64,108,30,114,33,66,184,251,130,64,108,4,186,31,66,24,82,103,64,108,245,233,29,66,124,22,74,64,108,26,3,28,66,84,87,46,64,108,171,6,26,66,92,38,20,64,108,215,163,25,66,40,92,15,64,108,
215,163,25,66,41,92,15,64,108,215,163,25,66,44,92,15,64,108,11,188,23,66,192,97,244,63,108,237,195,21,66,224,36,205,63,108,193,188,19,66,208,26,169,63,108,209,167,17,66,160,90,136,63,108,116,134,15,66,112,242,85,63,108,6,90,13,66,240,18,34,63,108,235,
35,11,66,160,111,234,62,108,142,229,8,66,160,251,158,62,108,93,160,6,66,128,244,67,62,108,206,85,4,66,0,74,206,61,108,86,7,2,66,0,15,31,61,108,225,108,255,65,0,56,191,59,108,205,204,252,65,0,0,0,0,108,205,204,252,65,0,0,0,0,108,205,204,252,65,0,0,0,0,
108,250,164,248,65,0,128,238,57,108,135,126,244,65,0,30,220,60,108,28,92,240,65,128,41,162,61,108,95,64,236,65,128,7,33,62,108,240,45,232,65,128,148,133,62,108,106,39,228,65,192,154,199,62,108,97,47,224,65,0,54,11,63,108,94,72,220,65,16,235,56,63,108,
226,116,216,65,64,207,108,63,108,94,183,212,65,176,96,147,63,108,31,133,211,65,168,112,157,63,108,31,133,211,65,164,112,157,63,108,31,133,211,65,168,112,157,63,108,38,65,208,65,8,197,188,63,108,69,23,205,65,240,171,222,63,108,132,9,202,65,204,135,1,64,
108,214,25,199,65,98,236,20,64,108,29,74,196,65,78,119,41,64,108,37,156,193,65,110,27,63,64,108,164,17,191,65,230,202,85,64,108,60,172,188,65,50,119,109,64,108,117,109,186,65,154,8,131,64,108,190,86,184,65,144,196,143,64,108,110,105,182,65,90,231,156,
64,108,193,166,180,65,143,104,170,64,108,104,102,180,65,225,122,172,64,108,103,102,180,65,225,122,172,64,108,102,102,180,65,227,122,172,64,108,85,58,178,65,2,116,193,64,108,12,82,176,65,151,213,214,64,108,195,174,174,65,242,145,236,64,108,135,81,173,
65,150,77,1,65,108,55,59,172,65,148,113,12,65,108,133,108,171,65,213,173,23,65,108,246,229,170,65,38,251,34,65,108,223,167,170,65,77,82,46,65,108,215,163,170,65,194,245,48,65,108,216,163,170,65,194,245,48,65,98,124,20,170,65,20,174,79,65,165,112,171,
65,122,20,110,65,1,0,172,65,225,122,134,65,98,1,0,172,65,225,122,142,65,103,102,172,65,225,122,150,65,93,143,172,65,225,122,158,65,108,93,143,172,65,41,92,159,65,108,93,143,172,65,41,92,159,65,108,18,0,172,65,14,130,161,65,108,112,140,171,65,110,174,
163,65,108,32,133,171,65,10,215,163,65,108,32,133,171,65,10,215,163,65,98,32,133,171,65,225,122,164,65,32,133,171,65,51,51,165,65,63,10,171,65,123,20,166,65,108,63,10,171,65,123,20,166,65,108,6,199,170,65,61,25,167,65,108,234,144,170,65,8,33,168,65,108,
15,104,170,65,50,43,169,65,108,143,76,170,65,19,55,170,65,108,123,62,170,65,253,67,171,65,108,114,61,170,65,164,112,171,65,108,114,61,170,65,164,112,171,65,108,114,61,170,65,164,112,171,65,108,78,63,170,65,1,44,172,65,108,134,74,170,65,10,231,172,65,
108,20,95,170,65,72,161,173,65,108,234,124,170,65,67,90,174,65,108,245,163,170,65,133,17,175,65,108,28,212,170,65,154,198,175,65,108,65,13,171,65,12,121,176,65,108,63,79,171,65,106,40,177,65,108,235,153,171,65,67,212,177,65,108,145,194,171,65,246,40,
178,65,108,145,194,171,65,246,40,178,65,108,145,194,171,65,246,40,178,65,108,84,42,172,65,73,229,178,65,108,96,155,172,65,48,156,179,65,108,107,21,173,65,55,77,180,65,108,41,152,173,65,235,247,180,65,108,135,235,173,65,41,92,181,65,108,135,235,173,65,
41,92,181,65,98,125,20,176,65,92,143,184,65,135,235,173,65,10,215,181,65,135,235,173,65,123,20,182,65,98,135,235,173,65,51,51,187,65,74,225,174,65,236,81,192,65,74,225,174,65,164,112,197,65,98,74,225,174,65,123,20,200,65,74,225,174,65,215,163,202,65,
74,225,174,65,164,112,205,65,108,2,0,174,65,133,235,207,65,108,2,0,174,65,133,235,207,65,108,178,149,171,65,102,105,213,65,108,229,229,168,65,157,198,218,65,108,82,242,165,65,190,255,223,65,108,156,153,163,65,143,194,227,65,108,156,153,163,65,143,194,
227,65,108,54,51,151,65,143,194,243,65,98,167,112,145,65,184,30,251,65,13,215,139,65,174,71,1,66,3,0,134,65,194,245,4,66,108,3,0,134,65,194,245,4,66,108,1,155,129,65,192,173,7,66,108,241,249,122,65,252,128,10,66,108,26,81,115,65,168,109,13,66,108,98,
64,108,65,228,113,16,66,108,107,102,102,65,112,61,19,66,108,108,102,102,65,112,61,19,66,108,108,102,102,65,113,61,19,66,108,244,218,94,65,104,179,24,66,108,96,105,88,65,195,63,30,66,108,182,71,85,65,102,102,33,66,108,180,71,85,65,102,102,33,66,108,182,
71,85,65,102,102,33,66,108,64,151,79,65,169,248,37,66,108,168,254,72,65,67,119,42,66,108,38,130,65,65,84,223,46,66,108,180,71,61,65,184,30,49,66,108,180,71,61,65,184,30,49,66,113,61,10,47,65,0,0,56,66,0,0,32,65,195,245,62,66,108,255,255,31,65,195,245,
62,66,108,88,123,28,65,150,155,64,66,108,36,76,25,65,35,76,66,66,108,111,116,22,65,85,6,68,66,108,9,246,19,65,18,201,69,66,108,141,210,17,65,56,147,71,66,108,86,11,16,65,163,99,73,66,108,255,255,15,65,164,112,73,66,108,0,0,16,65,164,112,73,66,108,0,0,
16,65,164,112,73,66,108,14,114,15,65,220,116,74,66,108,80,24,15,65,135,122,75,66,108,254,242,14,65,254,128,76,66,108,49,2,15,65,152,135,77,66,108,222,69,15,65,173,141,78,66,108,219,189,15,65,150,146,79,66,108,0,0,16,65,0,0,80,66,108,0,0,16,65,0,0,80,
66,108,0,0,16,65,0,0,80,66,108,19,74,12,65,237,88,81,66,108,75,218,8,65,74,189,82,66,108,246,40,8,65,61,10,83,66,108,246,40,8,65,61,10,83,66,108,246,40,8,65,61,10,83,66,108,62,245,3,65,173,219,84,66,108,164,203,254,64,22,159,86,66,108,226,122,252,64,
61,10,87,66,108,226,122,252,64,61,10,87,66,108,226,122,252,64,61,10,87,66,108,195,132,250,64,133,102,87,66,108,95,106,248,64,141,191,87,66,108,14,45,246,64,27,21,88,66,108,64,206,243,64,249,102,88,66,108,120,79,241,64,242,180,88,66,108,80,178,238,64,
213,254,88,66,108,114,248,235,64,114,68,89,66,108,160,35,233,64,156,133,89,66,108,166,53,230,64,43,194,89,66,108,184,30,229,64,10,215,89,66,108,185,30,229,64,10,215,89,66,108,185,30,229,64,10,215,89,66,108,77,200,225,64,107,14,90,66,108,206,92,222,64,
101,64,90,66,108,108,222,218,64,214,108,90,66,108,100,79,215,64,162,147,90,66,108,251,177,211,64,177,180,90,66,108,131,8,208,64,238,207,90,66,108,82,85,204,64,70,229,90,66,108,200,154,200,64,173,244,90,66,108,71,219,196,64,24,254,90,66,108,32,133,195,
64,0,0,91,66,108,32,133,195,64,0,0,91,66,98,114,61,186,64,0,0,91,66,155,153,177,64,0,0,91,66,216,163,168,64,0,0,91,66,108,10,215,155,64,0,0,91,66,108,10,215,155,64,0,0,91,66,108,122,219,147,64,146,239,90,66,108,229,219,139,64,238,235,90,66,108,107,221,
131,64,22,245,90,66,108,82,202,119,64,4,11,91,66,108,112,240,103,64,169,45,91,66,108,30,133,91,64,236,81,91,66,108,30,133,91,64,236,81,91,66,108,30,133,91,64,236,81,91,66,108,35,147,82,64,205,112,91,66,108,183,188,73,64,203,150,91,66,108,128,7,65,64,
206,195,91,66,108,16,121,56,64,186,247,91,66,108,227,22,48,64,108,50,92,66,108,84,230,39,64,192,115,92,66,108,162,236,31,64,140,187,92,66,108,230,46,24,64,161,9,93,66,108,20,178,16,64,206,93,93,66,108,249,122,9,64,221,183,93,66,108,49,142,2,64,148,23,
94,66,108,0,0,0,64,113,61,94,66,108,0,0,0,64,113,61,94,66,108,254,255,255,63,113,61,94,66,108,198,203,242,63,227,179,94,66,108,54,89,230,63,118,47,95,66,108,70,176,218,63,219,175,95,66,108,102,216,207,63,193,52,96,66,108,142,216,197,63,211,189,96,66,
108,34,183,188,63,184,74,97,66,108,248,121,180,63,22,219,97,66,108,84,38,173,63,146,110,98,66,108,232,192,166,63,204,4,99,66,108,202,77,161,63,101,157,99,66,108,122,208,156,63,251,55,100,66,108,244,40,156,63,236,81,100,66,108,246,40,156,63,236,81,100,
66,108,244,40,156,63,236,81,100,66,108,112,165,150,63,151,120,101,66,108,248,250,146,63,25,161,102,66,108,224,43,145,63,178,202,103,66,108,84,57,145,63,166,244,104,66,108,72,35,147,63,53,30,106,66,108,224,122,148,63,154,153,106,66,108,226,122,148,63,
154,153,106,66,98,226,122,148,63,93,143,108,66,1,0,160,63,154,153,110,66,103,102,166,63,103,102,112,66,98,205,204,172,63,52,51,114,66,62,10,183,63,1,0,117,66,72,225,186,63,236,81,119,66,108,72,225,186,63,236,81,119,66,108,92,185,189,63,144,183,120,66,
108,136,84,190,63,228,29,122,66,108,108,178,188,63,4,132,123,66,108,20,212,184,63,10,233,124,66,108,248,187,178,63,18,76,126,66,108,0,110,170,63,56,172,127,66,108,124,239,159,63,78,132,128,66,108,36,71,147,63,47,48,129,66,108,196,245,136,63,246,168,129,
66,108,195,245,136,63,246,168,129,66,98,144,194,117,63,51,51,130,66,226,122,84,63,82,184,130,66,52,51,51,63,113,61,131,66,108,48,51,51,63,113,61,131,66,108,192,247,250,62,153,19,132,66,108,128,95,154,62,218,238,132,66,108,128,194,117,62,113,61,133,66,
108,146,194,117,62,113,61,133,66,108,144,194,117,62,113,61,133,66,108,0,106,59,62,41,137,133,66,108,176,181,8,62,62,214,133,66,108,0,140,187,61,126,36,134,66,108,0,218,106,61,185,115,134,66,108,0,236,252,60,186,195,134,66,108,0,200,72,60,78,20,135,66,
108,0,208,199,58,68,101,135,66,108,0,0,0,0,225,122,135,66,108,0,0,0,0,225,122,135,66,108,0,0,128,52,225,122,135,66,108,0,232,222,186,244,179,135,66,108,0,92,14,59,0,237,135,66,108,0,51,62,60,225,37,136,66,108,0,203,217,60,114,94,136,66,108,64,200,64,
61,142,150,136,66,108,192,127,149,61,18,206,136,66,108,160,163,213,61,219,4,137,66,108,96,83,16,62,197,58,137,66,108,144,44,59,62,173,111,137,66,108,240,65,107,62,115,163,137,66,108,92,58,144,62,244,213,137,66,108,160,153,153,62,102,230,137,66,108,154,
153,153,62,102,230,137,66,108,152,153,153,62,102,230,137,66,108,128,201,188,62,40,28,138,66,108,244,157,226,62,22,80,138,66,108,96,127,5,63,16,130,138,66,108,2,233,26,63,245,177,138,66,108,50,126,49,63,167,223,138,66,108,122,48,73,63,9,11,139,66,108,
180,240,97,63,254,51,139,66,108,6,175,123,63,109,90,139,66,108,127,45,139,63,60,126,139,66,108,193,241,152,63,86,159,139,66,108,124,27,167,63,165,189,139,66,108,160,161,181,63,21,217,139,66,108,166,112,189,63,102,230,139,66,108,164,112,189,63,102,230,
139,66,108,160,112,189,63,102,230,139,66,108,93,221,217,63,63,24,140,66,108,118,224,246,63,90,68,140,66,108,173,51,10,64,154,106,140,66,108,146,47,25,64,230,138,140,66,108,30,133,27,64,92,143,140,66,108,31,133,27,64,92,143,140,66,108,52,51,51,64,143,
194,140,66,98,185,30,85,64,61,10,141,66,62,10,119,64,102,102,141,66,226,122,140,64,112,189,141,66,108,195,245,176,64,194,117,142,66,98,0,0,216,64,51,51,143,66,246,40,0,65,143,194,143,66,21,174,19,65,235,81,144,66,108,21,174,19,65,234,81,144,66,108,82,
132,47,65,96,26,145,66,108,129,1,75,65,27,15,146,66,108,12,20,102,65,126,47,147,66,108,246,40,104,65,174,71,147,66,108,246,40,104,65,174,71,147,66,108,246,40,120,65,123,20,148,66,108,246,40,120,65,123,20,148,66,108,56,114,127,65,31,126,148,66,108,178,
113,131,65,250,219,148,66,108,218,59,135,65,208,45,149,66,108,39,21,139,65,109,115,149,66,108,36,251,142,65,163,172,149,66,108,82,235,146,65,79,217,149,66,108,44,227,150,65,84,249,149,66,108,255,255,151,65,0,0,150,66,108,0,0,152,65,0,0,150,66,108,61,
10,153,65,0,0,150,66,108,61,10,153,65,0,0,150,66,108,250,95,155,65,252,251,149,66,108,42,180,157,65,130,240,149,66,108,80,5,160,65,152,221,149,66,108,240,81,162,65,75,195,149,66,108,146,152,164,65,172,161,149,66,108,192,215,166,65,208,120,149,66,108,
12,14,169,65,209,72,149,66,108,10,58,171,65,206,17,149,66,108,86,90,173,65,234,211,148,66,108,150,109,175,65,77,143,148,66,108,0,0,176,65,225,122,148,66,108,0,0,176,65,225,122,148,66,108,255,255,175,65,225,122,148,66,108,111,241,177,65,153,45,148,66,
108,204,210,179,65,50,218,147,66,108,226,162,181,65,226,128,147,66,108,138,96,183,65,226,33,147,66,108,164,10,185,65,111,189,146,66,108,34,160,186,65,201,83,146,66,108,255,31,188,65,52,229,145,66,108,70,137,189,65,247,113,145,66,108,15,219,190,65,91,
250,144,66,108,130,20,192,65,172,126,144,66,108,50,51,193,65,0,0,144,66,108,51,51,193,65,0,0,144,66,108,51,51,193,65,0,0,144,66,108,251,51,194,65,179,122,143,66,108,204,25,195,65,92,242,142,66,108,16,228,195,65,81,103,142,66,108,102,102,196,65,0,0,142,
66,108,102,102,196,65,0,0,142,66,108,101,102,196,65,0,0,142,66,108,43,217,202,65,102,147,142,66,108,88,103,209,65,253,17,143,66,108,187,12,216,65,115,123,143,66,108,19,197,222,65,133,207,143,66,108,20,140,229,65,254,13,144,66,108,102,93,236,65,181,54,
144,66,108,174,52,243,65,144,73,144,66,108,163,112,249,65,174,71,144,66,108,164,112,249,65,174,71,144,66,108,163,112,249,65,174,71,144,66,108,49,249,255,65,182,40,144,66,108,187,60,3,66,225,244,143,66,108,166,118,6,66,82,172,143,66,108,71,168,9,66,54,
79,143,66,108,148,207,12,66,201,221,142,66,108,137,234,15,66,84,88,142,66,108,40,247,18,66,44,191,141,66,108,174,71,19,66,20,174,141,66,108,174,71,19,66,20,174,141,66,98,174,71,23,66,225,250,141,66,174,71,27,66,102,102,142,66,174,71,31,66,10,215,142,
66,98,123,20,31,66,71,225,143,66,133,235,30,66,164,240,144,66,133,235,30,66,30,5,146,66,108,133,235,30,66,30,5,146,66,108,117,229,30,66,57,150,146,66,108,232,237,30,66,76,39,147,66,108,218,4,31,66,251,183,147,66,108,58,42,31,66,232,71,148,66,108,241,
93,31,66,185,214,148,66,108,222,159,31,66,17,100,149,66,108,215,239,31,66,150,239,149,66,108,169,77,32,66,239,120,150,66,108,23,185,32,66,196,255,150,66,108,221,49,33,66,190,131,151,66,108,174,183,33,66,137,4,152,66,108,82,184,33,66,30,5,152,66,108,82,
184,33,66,30,5,152,66,108,82,184,33,66,30,5,152,66,108,228,84,34,66,184,113,152,66,108,30,252,34,66,69,218,152,66,108,151,173,35,66,131,62,153,66,108,220,104,36,66,49,158,153,66,108,117,45,37,66,19,249,153,66,108,229,250,37,66,238,78,154,66,108,168,208,
38,66,139,159,154,66,108,54,174,39,66,183,234,154,66,108,0,147,40,66,65,48,155,66,108,117,126,41,66,254,111,155,66,108,253,111,42,66,196,169,155,66,108,254,102,43,66,110,221,155,66,108,225,122,43,66,71,225,155,66,108,225,122,43,66,71,225,155,66,108,225,
122,43,66,71,225,155,66,108,65,231,44,66,120,46,156,66,108,228,90,46,66,118,114,156,66,108,221,212,47,66,21,173,156,66,108,56,84,49,66,46,222,156,66,108,1,216,50,66,164,5,157,66,108,64,95,52,66,92,35,157,66,108,250,232,53,66,68,55,157,66,108,51,116,55,
66,78,65,157,66,108,123,20,56,66,143,66,157,66,108,123,20,56,66,143,66,157,66,108,123,20,56,66,143,66,157,66,108,191,99,57,66,126,63,157,66,108,74,178,58,66,14,52,157,66,108,70,255,59,66,68,32,157,66,108,123,20,60,66,184,30,157,66,108,123,20,60,66,184,
30,157,66,108,123,20,60,66,184,30,157,66,108,84,127,61,66,218,252,156,66,108,86,230,62,66,246,209,156,66,108,155,72,64,66,39,158,156,66,108,66,165,65,66,142,97,156,66,108,106,251,66,66,83,28,156,66,108,57,74,68,66,160,206,155,66,108,217,144,69,66,169,
120,155,66,108,120,206,70,66,163,26,155,66,108,76,2,72,66,204,180,154,66,108,205,204,72,66,133,107,154,66,108,205,204,72,66,133,107,154,66,108,204,204,72,66,133,107,154,66,108,101,58,75,66,36,101,153,66,108,253,140,77,66,142,79,152,66,108,24,195,79,66,
118,43,151,66,108,0,0,80,66,60,10,151,66,108,0,0,80,66,61,10,151,66,108,205,204,81,66,245,40,150,66,108,206,204,81,66,245,40,150,66,108,148,110,84,66,162,238,148,66,108,237,46,87,66,138,197,147,66,108,23,12,90,66,106,174,146,66,108,1,0,92,66,0,0,146,
66,108,0,0,92,66,0,0,146,66,108,0,0,92,66,0,0,146,66,108,198,218,96,66,44,146,144,66,108,145,216,101,66,220,67,143,66,108,92,143,104,66,184,158,142,66,108,92,143,104,66,184,158,142,66,108,194,245,109,66,174,71,141,66,108,194,245,109,66,174,71,141,66,
108,98,121,111,66,194,235,140,66,108,86,243,112,66,68,134,140,66,108,171,98,114,66,117,23,140,66,108,120,198,115,66,155,159,139,66,108,216,29,117,66,3,31,139,66,108,239,103,118,66,0,150,138,66,108,234,163,119,66,233,4,138,66,108,0,209,120,66,26,108,137,
66,108,122,20,121,66,174,71,137,66,108,122,20,121,66,174,71,137,66,108,122,20,121,66,174,71,137,66,108,43,188,121,66,81,223,136,66,108,55,89,122,66,228,114,136,66,108,59,235,122,66,173,2,136,66,108,217,113,123,66,244,142,135,66,108,186,236,123,66,3,24,
135,66,108,145,91,124,66,37,158,134,66,108,153,153,124,66,235,81,134,66,108,153,153,124,66,235,81,134,66,108,153,153,124,66,184,30,134,66,108,153,153,124,66,184,30,134,66,108,20,189,124,66,153,218,133,66,108,181,217,124,66,173,149,133,66,108,104,239,
124,66,32,80,133,66,108,34,254,124,66,31,10,133,66,108,215,5,125,66,213,195,132,66,108,130,6,125,66,113,125,132,66,108,37,0,125,66,31,55,132,66,108,194,242,124,66,12,241,131,66,108,98,222,124,66,101,171,131,66,108,18,195,124,66,87,102,131,66,108,228,
160,124,66,14,34,131,66,108,238,119,124,66,181,222,130,66,108,73,72,124,66,119,156,130,66,108,21,18,124,66,128,91,130,66,108,0,0,124,66,174,71,130,66,108,0,0,124,66,174,71,130,66,99,109,123,20,252,65,174,71,77,65,108,122,20,252,65,174,71,77,65,108,97,
172,252,65,253,78,74,65,108,25,87,253,65,111,102,71,65,108,54,20,254,65,223,143,68,65,108,63,227,254,65,31,205,65,65,108,175,195,255,65,242,31,63,65,108,123,90,0,66,17,138,60,65,108,61,219,0,66,33,13,58,65,108,204,99,1,66,186,170,55,65,108,207,243,1,
66,100,100,53,65,108,234,138,2,66,146,59,51,65,108,190,40,3,66,166,49,49,65,108,229,204,3,66,240,71,47,65,108,113,61,4,66,123,20,46,65,108,113,61,4,66,123,20,46,65,108,113,61,4,66,123,20,46,65,108,140,172,4,66,19,221,44,65,108,103,31,5,66,69,188,43,65,
108,186,149,5,66,202,178,42,65,108,56,15,6,66,75,193,41,65,108,147,139,6,66,100,232,40,65,108,62,10,7,66,246,40,40,65,108,62,10,7,66,246,40,40,65,108,62,10,7,66,246,40,40,65,108,118,129,7,66,108,116,39,65,108,201,250,7,66,243,215,38,65,108,233,117,8,
66,236,83,38,65,108,137,242,8,66,173,232,37,65,108,88,112,9,66,123,150,37,65,108,5,239,9,66,137,93,37,65,108,64,110,10,66,253,61,37,65,108,183,237,10,66,234,55,37,65,108,25,109,11,66,85,75,37,65,108,20,236,11,66,49,120,37,65,108,87,106,12,66,98,190,37,
65,108,164,112,12,66,144,194,37,65,108,164,112,12,66,144,194,37,65,108,164,112,12,66,144,194,37,65,108,141,4,13,66,57,25,38,65,108,49,151,13,66,88,141,38,65,108,51,40,14,66,163,30,39,65,108,54,183,14,66,189,204,39,65,108,223,67,15,66,54,151,40,65,108,
211,205,15,66,141,125,41,65,108,185,84,16,66,46,127,42,65,108,61,216,16,66,118,155,43,65,108,9,88,17,66,172,209,44,65,108,31,133,17,66,175,71,45,65,108,31,133,17,66,175,71,45,65,108,30,133,17,66,175,71,45,65,108,101,50,18,66,126,58,47,65,108,56,217,18,
66,82,79,49,65,108,45,121,19,66,213,132,51,65,108,222,17,20,66,158,217,53,65,108,234,162,20,66,46,76,56,65,108,243,43,21,66,245,218,58,65,108,162,172,21,66,80,132,61,65,108,164,36,22,66,139,70,64,65,108,173,147,22,66,225,31,67,65,108,117,249,22,66,129,
14,70,65,108,188,85,23,66,137,16,73,65,108,70,168,23,66,14,36,76,65,108,222,240,23,66,23,71,79,65,108,0,0,24,66,0,0,80,65,108,0,0,24,66,0,0,80,65,108,0,0,24,66,255,255,79,65,108,218,94,24,66,146,247,84,65,108,177,173,24,66,131,0,90,65,108,84,236,24,66,
156,23,95,65,108,156,26,25,66,153,57,100,65,108,105,56,25,66,50,99,105,65,108,170,69,25,66,26,145,110,65,108,85,66,25,66,0,192,115,65,108,51,51,25,66,255,255,119,65,108,51,51,25,66,0,0,120,65,108,51,51,25,66,0,0,120,65,108,99,20,25,66,24,81,124,65,108,
206,231,24,66,83,77,128,65,108,144,173,24,66,246,108,130,65,108,208,101,24,66,24,134,132,65,108,185,16,24,66,98,151,134,65,108,0,0,24,66,195,245,134,65,108,0,0,24,66,195,245,134,65,108,205,204,22,66,21,174,133,65,108,205,204,22,66,21,174,133,65,108,150,
213,21,66,205,229,132,65,108,174,217,20,66,124,54,132,65,108,181,217,19,66,144,160,131,65,108,236,81,19,66,41,92,131,65,108,236,81,19,66,41,92,131,65,108,235,81,19,66,41,92,131,65,108,78,142,19,66,151,207,130,65,108,25,199,19,66,40,61,130,65,108,42,252,
19,66,59,165,129,65,108,255,255,19,66,154,153,129,65,108,0,0,20,66,154,153,129,65,108,0,0,20,66,154,153,129,65,108,234,53,20,66,165,195,128,65,108,105,102,20,66,33,209,127,65,108,95,145,20,66,210,17,126,65,108,177,182,20,66,124,74,124,65,108,70,214,20,
66,65,124,122,65,108,11,240,20,66,74,168,120,65,108,238,3,21,66,194,207,118,65,108,228,17,21,66,216,243,116,65,108,123,20,21,66,226,122,116,65,108,123,20,21,66,226,122,116,65,108,123,20,21,66,226,122,116,65,108,18,38,21,66,122,86,114,65,108,201,48,21,
66,61,47,112,65,108,153,52,21,66,140,6,110,65,108,129,49,21,66,201,221,107,65,108,129,39,21,66,85,182,105,65,108,160,22,21,66,145,145,103,65,108,234,254,20,66,220,112,101,65,108,108,224,20,66,148,85,99,65,108,60,187,20,66,16,65,97,65,108,112,143,20,66,
166,52,95,65,108,37,93,20,66,165,49,93,65,108,122,36,20,66,87,57,91,65,108,0,0,20,66,123,20,90,65,108,0,0,20,66,123,20,90,65,108,0,0,20,66,123,20,90,65,108,160,200,19,66,144,107,88,65,108,3,140,19,66,63,206,86,65,108,80,74,19,66,144,61,85,65,108,175,
3,19,66,131,186,83,65,108,80,184,18,66,17,70,82,65,108,97,104,18,66,40,225,80,65,108,22,20,18,66,172,140,79,65,108,164,187,17,66,119,73,78,65,108,70,95,17,66,87,24,77,65,108,53,255,16,66,17,250,75,65,108,174,155,16,66,90,239,74,65,108,243,52,16,66,223,
248,73,65,108,68,203,15,66,60,23,73,65,108,229,94,15,66,2,75,72,65,108,51,51,15,66,0,0,72,65,108,51,51,15,66,0,0,72,65,108,51,51,15,66,0,0,72,65,108,163,196,14,66,176,150,71,65,108,230,84,14,66,155,67,71,65,108,67,228,13,66,248,6,71,65,108,3,115,13,66,
237,224,70,65,108,108,1,13,66,146,209,70,65,108,201,143,12,66,241,216,70,65,108,102,102,12,66,72,225,70,65,108,102,102,12,66,72,225,70,65,108,102,102,12,66,72,225,70,65,108,102,17,12,66,18,6,71,65,108,247,188,11,66,207,59,71,65,108,79,105,11,66,91,130,
71,65,108,164,22,11,66,138,217,71,65,108,41,197,10,66,36,65,72,65,108,21,117,10,66,232,184,72,65,108,152,38,10,66,135,64,73,65,108,231,217,9,66,171,215,73,65,108,50,143,9,66,244,125,74,65,108,102,102,9,66,72,225,74,65,108,102,102,9,66,72,225,74,65,108,
102,102,9,66,72,225,74,65,108,162,21,9,66,94,193,75,65,108,196,199,8,66,82,177,76,65,108,255,124,8,66,138,176,77,65,108,130,53,8,66,99,190,78,65,108,123,241,7,66,48,218,79,65,108,22,177,7,66,60,3,81,65,108,123,116,7,66,201,56,82,65,108,210,59,7,66,17,
122,83,65,108,51,51,7,66,21,174,83,65,108,51,51,7,66,21,174,83,65,108,51,51,7,66,22,174,83,65,108,212,232,6,66,166,142,85,65,108,142,164,6,66,122,125,87,65,108,140,102,6,66,86,121,89,65,108,247,46,6,66,246,128,91,65,108,242,253,5,66,11,147,93,65,108,
156,211,5,66,68,174,95,65,108,16,176,5,66,71,209,97,65,108,101,147,5,66,182,250,99,65,108,174,125,5,66,48,41,102,65,108,248,110,5,66,78,91,104,65,108,77,103,5,66,169,143,106,65,108,102,102,5,66,52,51,107,65,108,102,102,5,66,52,51,107,65,108,102,102,5,
66,52,51,107,65,108,201,97,5,66,79,71,109,65,108,212,99,5,66,172,91,111,65,108,102,102,5,66,247,40,112,65,108,102,102,5,66,247,40,112,65,108,0,0,4,66,205,204,108,65,108,0,0,4,66,205,204,108,65,108,187,82,2,66,125,71,105,65,108,189,154,0,66,31,25,102,
65,108,60,178,253,65,188,67,99,65,108,184,30,251,65,164,112,97,65,108,184,30,251,65,164,112,97,65,108,184,30,251,65,164,112,97,65,108,183,30,251,65,164,112,97,65,108,172,11,251,65,169,113,94,65,108,209,11,251,65,189,113,91,65,108,39,31,251,65,202,114,
88,65,108,162,69,251,65,188,118,85,65,108,40,127,251,65,122,127,82,65,108,148,203,251,65,235,142,79,65,108,122,20,252,65,174,71,77,65,108,123,20,252,65,174,71,77,65,99,109,225,122,25,66,51,51,169,65,98,225,122,25,66,123,20,170,65,112,61,25,66,61,10,171,
65,245,40,25,66,133,235,171,65,108,245,40,25,66,184,30,173,65,108,246,40,25,66,184,30,173,65,108,47,38,25,66,221,211,173,65,108,226,30,25,66,129,136,174,65,108,20,19,25,66,48,60,175,65,108,204,2,25,66,119,238,175,65,108,21,238,24,66,229,158,176,65,108,
252,212,24,66,9,77,177,65,108,145,183,24,66,115,248,177,65,108,153,153,24,66,92,143,178,65,108,153,153,24,66,92,143,178,65,108,153,153,24,66,92,143,178,65,108,153,117,24,66,90,5,179,65,108,178,78,24,66,154,119,179,65,108,253,36,24,66,210,229,179,65,108,
148,248,23,66,187,79,180,65,108,147,201,23,66,18,181,180,65,108,25,152,23,66,149,21,181,65,108,70,100,23,66,8,113,181,65,108,58,46,23,66,47,199,181,65,108,25,246,22,66,212,23,182,65,108,5,188,22,66,195,98,182,65,108,37,128,22,66,203,167,182,65,108,158,
66,22,66,193,230,182,65,108,152,3,22,66,125,31,183,65,108,133,235,21,66,51,51,183,65,108,133,235,21,66,51,51,183,65,108,133,235,21,66,51,51,183,65,108,114,47,21,66,55,213,183,65,108,143,111,20,66,59,100,184,65,108,205,204,19,66,205,204,184,65,108,205,
204,19,66,205,204,184,65,108,21,174,18,66,31,133,185,65,108,21,174,18,66,32,133,185,65,108,161,49,17,66,173,224,186,65,108,86,190,15,66,210,97,188,65,108,34,85,14,66,154,7,190,65,108,236,246,12,66,246,208,191,65,108,148,164,11,66,192,188,193,65,108,242,
94,10,66,192,201,195,65,108,52,51,10,66,124,20,196,65,108,52,51,10,66,123,20,196,65,108,52,51,10,66,122,20,196,65,108,234,10,8,66,16,102,199,65,108,21,206,5,66,96,127,202,65,108,52,51,5,66,174,71,203,65,108,52,51,5,66,174,71,203,65,108,52,51,5,66,174,
71,203,65,108,48,213,3,66,229,218,204,65,108,136,109,2,66,158,74,206,65,108,36,253,0,66,238,149,207,65,108,218,9,255,65,0,188,208,65,108,172,11,252,65,26,188,209,65,108,73,225,250,65,123,20,210,65,108,73,225,250,65,123,20,210,65,108,72,225,250,65,123,
20,210,65,108,49,184,248,65,11,190,210,65,108,81,135,246,65,192,75,211,65,108,16,80,244,65,64,189,211,65,108,216,19,242,65,66,18,212,65,108,23,212,239,65,142,74,212,65,108,62,146,237,65,3,102,212,65,108,191,79,235,65,141,100,212,65,108,11,14,233,65,46,
70,212,65,108,215,163,232,65,112,61,212,65,108,216,163,232,65,113,61,212,65,108,216,163,232,65,113,61,212,65,108,25,49,231,65,85,23,212,65,108,185,192,229,65,190,222,211,65,108,163,83,228,65,208,147,211,65,108,192,234,226,65,187,54,211,65,108,248,134,
225,65,186,199,210,65,108,46,41,224,65,21,71,210,65,108,65,210,222,65,29,181,209,65,108,14,131,221,65,48,18,209,65,108,107,60,220,65,183,94,208,65,108,41,255,218,65,36,155,207,65,108,247,40,218,65,62,10,207,65,108,247,40,218,65,62,10,207,65,108,247,40,
218,65,62,10,207,65,108,196,164,216,65,45,219,205,65,108,50,48,215,65,22,153,204,65,108,48,204,213,65,200,68,203,65,108,163,121,212,65,27,223,201,65,108,98,57,211,65,245,104,200,65,108,247,40,210,65,62,10,199,65,108,247,40,210,65,62,10,199,65,108,247,
40,210,65,62,10,199,65,108,75,195,212,65,247,139,199,65,108,71,99,215,65,57,236,199,65,108,59,7,218,65,198,42,200,65,108,42,92,219,65,113,61,200,65,108,42,92,219,65,113,61,200,65,108,175,71,221,65,113,61,200,65,108,175,71,221,65,113,61,200,65,108,238,
138,226,65,26,4,200,65,108,161,201,231,65,129,135,199,65,108,107,0,237,65,244,199,198,65,108,185,30,241,65,0,0,198,65,108,185,30,241,65,0,0,198,65,108,185,30,241,65,0,0,198,65,108,16,91,246,65,184,223,196,65,108,83,135,251,65,208,124,195,65,108,24,80,
0,66,42,216,193,65,108,72,225,0,66,164,112,193,65,108,72,225,0,66,164,112,193,65,108,72,225,0,66,164,112,193,65,108,53,27,3,66,175,118,191,65,108,199,71,5,66,100,68,189,65,108,154,101,7,66,42,219,186,65,108,84,115,9,66,142,60,184,65,108,162,111,11,66,
58,106,181,65,108,92,143,12,66,21,174,179,65,108,92,143,12,66,21,174,179,65,98,10,215,13,66,21,174,177,65,61,10,15,66,21,174,175,65,92,143,16,66,175,71,173,65,108,215,163,17,66,42,92,171,65,108,215,163,17,66,42,92,171,65,108,184,30,18,66,42,92,171,65,
108,184,30,18,66,42,92,171,65,108,111,144,18,66,208,121,171,65,108,191,2,19,66,15,140,171,65,108,95,117,19,66,218,146,171,65,108,6,232,19,66,47,142,171,65,108,107,90,20,66,15,126,171,65,108,67,204,20,66,132,98,171,65,108,71,225,20,66,42,92,171,65,108,
71,225,20,66,42,92,171,65,108,71,225,20,66,42,92,171,65,108,226,88,21,66,177,78,171,65,108,1,208,21,66,71,53,171,65,108,87,70,22,66,253,15,171,65,108,152,187,22,66,235,222,170,65,108,122,47,23,66,48,162,170,65,108,91,143,23,66,103,102,170,65,108,91,143,
23,66,103,102,170,65,108,91,143,23,66,103,102,170,65,108,188,240,23,66,89,63,170,65,108,4,81,24,66,155,14,170,65,108,246,175,24,66,78,212,169,65,108,84,13,25,66,149,144,169,65,108,227,104,25,66,157,67,169,65,108,225,122,25,66,51,51,169,65,108,225,122,
25,66,51,51,169,65,99,109,122,20,188,65,102,102,74,65,108,122,20,188,65,102,102,74,65,108,63,115,188,65,241,81,72,65,108,52,223,188,65,159,71,70,65,108,21,88,189,65,191,72,68,65,108,146,221,189,65,151,86,66,65,108,88,111,190,65,103,114,64,65,108,10,13,
191,65,100,157,62,65,108,64,182,191,65,186,216,60,65,108,145,106,192,65,139,37,59,65,108,136,41,193,65,237,132,57,65,108,20,174,193,65,225,122,56,65,108,20,174,193,65,225,122,56,65,108,20,174,193,65,225,122,56,65,108,112,72,194,65,192,109,55,65,108,85,
233,194,65,100,112,54,65,108,90,144,195,65,110,131,53,65,108,23,61,196,65,117,167,52,65,108,27,239,196,65,7,221,51,65,108,245,165,197,65,166,36,51,65,108,49,97,198,65,198,126,50,65,108,85,32,199,65,210,235,49,65,108,233,226,199,65,41,108,49,65,108,111,
168,200,65,28,0,49,65,108,105,112,201,65,239,167,48,65,108,87,58,202,65,220,99,48,65,108,184,5,203,65,14,52,48,65,108,174,71,203,65,246,40,48,65,108,174,71,203,65,246,40,48,65,108,174,71,203,65,246,40,48,65,108,163,71,204,65,98,35,48,65,108,106,71,205,
65,101,55,48,65,108,96,70,206,65,244,100,48,65,108,224,67,207,65,239,171,48,65,108,73,63,208,65,43,12,49,65,108,250,55,209,65,106,133,49,65,108,83,45,210,65,94,23,50,65,108,185,30,211,65,169,193,50,65,108,174,71,211,65,72,225,50,65,108,174,71,211,65,
72,225,50,65,108,174,71,211,65,72,225,50,65,108,201,59,212,65,104,224,51,65,108,54,41,213,65,157,247,52,65,108,93,15,214,65,52,38,54,65,108,170,237,214,65,108,107,55,65,108,144,195,215,65,117,198,56,65,108,133,144,216,65,112,54,58,65,108,7,84,217,65,
114,186,59,65,108,20,174,217,65,226,122,60,65,108,20,174,217,65,226,122,60,65,108,20,174,217,65,226,122,60,65,108,215,224,218,65,68,64,63,65,108,126,1,220,65,107,35,66,65,108,80,15,221,65,129,34,69,65,108,160,9,222,65,154,59,72,65,108,207,239,222,65,
186,108,75,65,108,72,193,223,65,215,179,78,65,108,134,125,224,65,216,14,82,65,108,17,36,225,65,151,123,85,65,108,20,174,225,65,206,204,88,65,108,20,174,225,65,206,204,88,65,108,20,174,225,65,206,204,88,65,108,158,80,226,65,50,35,93,65,108,53,215,226,
65,114,136,97,65,108,131,65,227,65,190,249,101,65,108,30,133,227,65,144,194,105,65,108,30,133,227,65,144,194,105,65,108,30,133,227,65,143,194,105,65,108,236,159,224,65,220,221,106,65,108,188,194,221,65,228,66,108,65,108,98,239,218,65,196,240,109,65,108,
225,122,218,65,112,61,110,65,108,225,122,218,65,113,61,110,65,108,225,122,218,65,114,61,110,65,108,76,52,218,65,105,98,108,65,108,239,225,217,65,7,143,106,65,108,254,131,217,65,118,196,104,65,108,181,26,217,65,219,3,103,65,108,88,166,216,65,87,78,101,
65,108,50,39,216,65,255,164,99,65,108,146,157,215,65,230,8,98,65,108,211,9,215,65,18,123,96,65,108,82,108,214,65,130,252,94,65,108,116,197,213,65,43,142,93,65,108,164,21,213,65,247,48,92,65,108,82,184,212,65,32,133,91,65,108,82,184,212,65,31,133,91,65,
108,82,184,212,65,31,133,91,65,108,193,79,212,65,53,205,90,65,108,184,226,211,65,251,31,90,65,108,126,113,211,65,222,125,89,65,108,91,252,210,65,70,231,88,65,108,154,131,210,65,147,92,88,65,108,137,7,210,65,31,222,87,65,108,118,136,209,65,59,108,87,65,
108,180,6,209,65,46,7,87,65,108,148,130,208,65,59,175,86,65,108,0,0,208,65,102,102,86,65,108,0,0,208,65,102,102,86,65,108,0,0,208,65,102,102,86,65,108,182,156,207,65,101,52,86,65,108,76,56,207,65,98,12,86,65,108,2,211,206,65,116,238,85,65,108,24,109,
206,65,177,218,85,65,108,209,6,206,65,35,209,85,65,108,110,160,205,65,210,209,85,65,108,47,58,205,65,188,220,85,65,108,87,212,204,65,220,241,85,65,108,39,111,204,65,34,17,86,65,108,223,10,204,65,125,58,86,65,108,192,167,203,65,208,109,86,65,108,9,70,
203,65,250,170,86,65,108,249,229,202,65,214,241,86,65,108,205,135,202,65,54,66,87,65,108,192,43,202,65,229,155,87,65,108,16,210,201,65,172,254,87,65,108,243,122,201,65,73,106,88,65,108,163,38,201,65,122,222,88,65,108,86,213,200,65,243,90,89,65,108,62,
135,200,65,100,223,89,65,108,143,60,200,65,122,107,90,65,108,120,245,199,65,217,254,90,65,108,38,178,199,65,37,153,91,65,108,197,114,199,65,250,57,92,65,108,126,55,199,65,241,224,92,65,108,117,0,199,65,160,141,93,65,108,207,205,198,65,152,63,94,65,108,
171,159,198,65,103,246,94,65,108,40,118,198,65,152,177,95,65,108,102,102,198,65,0,0,96,65,108,102,102,198,65,0,0,96,65,108,102,102,198,65,0,0,96,65,108,144,244,197,65,64,200,97,65,108,70,142,197,65,78,155,99,65,108,200,51,197,65,1,120,101,65,108,81,229,
196,65,39,93,103,65,108,19,163,196,65,138,73,105,65,108,55,109,196,65,238,59,107,65,108,102,102,196,65,31,133,107,65,108,102,102,196,65,31,133,107,65,108,102,102,196,65,31,133,107,65,108,134,60,196,65,250,111,110,65,108,94,37,196,65,22,94,113,65,108,
252,32,196,65,146,77,116,65,108,99,47,196,65,142,60,119,65,108,137,80,196,65,42,41,122,65,108,102,102,196,65,31,133,123,65,108,102,102,196,65,31,133,123,65,108,102,102,196,65,31,133,123,65,108,118,131,196,65,16,140,125,65,108,117,173,196,65,116,143,127,
65,108,71,228,196,65,0,199,128,65,108,202,39,197,65,55,195,129,65,108,211,119,197,65,189,187,130,65,108,30,133,197,65,72,225,130,65,108,30,133,197,65,72,225,130,65,108,225,122,196,65,21,174,131,65,108,225,122,196,65,21,174,131,65,108,186,232,193,65,154,
248,133,65,108,182,116,191,65,73,99,136,65,108,112,61,190,65,21,174,137,65,108,112,61,190,65,21,174,137,65,108,143,194,189,65,21,174,137,65,108,144,194,189,65,22,174,137,65,108,18,236,188,65,121,57,134,65,108,14,66,188,65,63,187,130,65,108,242,196,187,
65,72,107,126,65,108,15,117,187,65,209,85,119,65,108,42,92,187,65,45,92,115,65,108,41,92,187,65,42,92,115,65,108,41,92,187,65,43,92,115,65,108,11,2,187,65,181,1,110,65,108,74,202,186,65,244,159,104,65,108,8,181,186,65,88,58,99,65,108,83,194,186,65,87,
212,93,65,108,36,242,186,65,100,113,88,65,108,90,68,187,65,241,20,83,65,108,195,184,187,65,110,194,77,65,108,123,20,188,65,102,102,74,65,108,123,20,188,65,102,102,74,65,99,109,236,81,178,65,0,0,168,65,98,236,81,178,65,195,245,166,65,205,204,178,65,123,
20,166,65,195,245,178,65,174,71,165,65,98,185,30,179,65,225,122,164,65,164,112,179,65,205,204,162,65,144,194,179,65,20,174,161,65,108,144,194,179,65,20,174,161,65,108,171,68,180,65,100,109,160,65,108,164,214,180,65,156,51,159,65,108,29,120,181,65,131,
1,158,65,108,174,40,182,65,222,215,156,65,108,232,231,182,65,108,183,155,65,108,79,181,183,65,228,160,154,65,108,226,122,184,65,20,174,153,65,108,226,122,184,65,20,174,153,65,108,226,122,184,65,20,174,153,65,108,2,3,186,65,42,213,151,65,108,71,162,187,
65,112,16,150,65,108,168,87,189,65,9,97,148,65,108,12,34,191,65,8,200,146,65,108,226,122,192,65,20,174,145,65,108,226,122,192,65,20,174,145,65,108,93,143,194,65,0,0,144,65,108,52,51,195,65,164,112,143,65,98,113,61,196,65,113,61,142,65,165,112,197,65,
51,51,141,65,93,143,198,65,123,20,140,65,98,21,174,199,65,195,245,138,65,247,40,200,65,225,122,138,65,195,245,200,65,143,194,137,65,108,195,245,200,65,144,194,137,65,108,106,57,203,65,14,233,135,65,108,2,148,205,65,30,45,134,65,108,8,4,208,65,217,143,
132,65,108,240,135,210,65,72,18,131,65,108,26,30,213,65,96,181,129,65,108,226,196,215,65,0,122,128,65,108,147,122,218,65,228,193,126,65,108,195,245,218,65,102,102,126,65,108,195,245,218,65,102,102,126,65,108,144,194,219,65,102,102,126,65,108,144,194,
219,65,102,102,126,65,108,144,194,219,65,102,102,126,65,108,153,61,222,65,27,183,124,65,108,158,194,224,65,212,71,123,65,108,2,80,227,65,125,25,122,65,108,144,194,227,65,133,235,121,65,108,144,194,227,65,133,235,121,65,108,144,194,227,65,134,235,121,
65,108,114,6,230,65,76,57,121,65,108,15,78,232,65,64,193,120,65,108,241,151,234,65,178,131,120,65,108,144,194,235,65,226,122,120,65,108,144,194,235,65,225,122,120,65,108,144,194,235,65,226,122,120,65,108,103,194,237,65,196,143,120,65,108,21,193,239,65,
202,215,120,65,108,82,189,241,65,198,82,121,65,108,218,181,243,65,103,0,122,65,108,106,169,245,65,63,224,122,65,108,195,150,247,65,192,241,123,65,108,21,174,247,65,0,0,124,65,108,21,174,247,65,0,0,124,65,98,82,184,248,65,0,0,124,65,21,174,249,65,154,
153,125,65,82,184,250,65,102,102,126,65,108,82,184,250,65,102,102,126,65,108,17,155,254,65,236,218,128,65,108,178,51,1,66,214,179,130,65,108,154,153,1,66,184,30,131,65,108,154,153,1,66,184,30,131,65,108,154,153,6,66,102,102,136,65,108,154,153,6,66,102,
102,136,65,108,154,153,6,66,102,102,136,65,108,99,145,8,66,186,72,138,65,108,153,148,10,66,25,248,139,65,108,241,161,12,66,109,115,141,65,108,28,184,14,66,198,185,142,65,108,1,0,15,66,71,225,142,65,108,0,0,15,66,71,225,142,65,98,20,174,15,66,71,225,142,
65,174,71,16,66,143,194,143,65,195,245,16,66,122,20,144,65,98,113,61,18,66,122,20,144,65,72,225,18,66,122,20,152,65,41,92,20,66,122,20,152,65,108,41,92,20,66,122,20,152,65,108,92,165,20,66,190,22,152,65,108,105,238,20,66,82,32,152,65,108,34,55,21,66,
48,49,152,65,108,87,127,21,66,78,73,152,65,108,219,198,21,66,156,104,152,65,108,128,13,22,66,5,143,152,65,108,25,83,22,66,115,188,152,65,108,120,151,22,66,198,240,152,65,108,115,218,22,66,223,43,153,65,108,223,27,23,66,150,109,153,65,108,184,30,23,66,
163,112,153,65,108,184,30,23,66,163,112,153,65,108,184,30,23,66,163,112,153,65,108,99,92,23,66,166,183,153,65,108,53,152,23,66,188,4,154,65,108,6,210,23,66,181,87,154,65,108,178,9,24,66,90,176,154,65,108,21,63,24,66,116,14,155,65,108,13,114,24,66,198,
113,155,65,108,30,133,24,66,153,153,155,65,108,30,133,24,66,153,153,155,65,98,132,235,25,66,143,194,157,65,30,133,24,66,153,153,155,65,30,133,24,66,153,153,155,65,108,30,133,24,66,153,153,155,65,108,49,133,24,66,253,255,155,65,108,181,130,24,66,65,102,
156,65,108,172,125,24,66,38,204,156,65,108,24,118,24,66,105,49,157,65,108,255,107,24,66,201,149,157,65,108,103,95,24,66,8,249,157,65,108,88,80,24,66,228,90,158,65,108,220,62,24,66,31,187,158,65,108,253,42,24,66,124,25,159,65,108,202,20,24,66,191,117,
159,65,108,79,252,23,66,172,207,159,65,108,157,225,23,66,10,39,160,65,108,197,196,23,66,161,123,160,65,108,20,174,23,66,81,184,160,65,108,20,174,23,66,81,184,160,65,108,20,174,23,66,81,184,160,65,108,15,146,23,66,224,254,160,65,108,80,116,23,66,138,66,
161,65,108,233,84,23,66,38,131,161,65,108,239,51,23,66,137,192,161,65,108,118,17,23,66,141,250,161,65,108,150,237,22,66,13,49,162,65,108,101,200,22,66,229,99,162,65,108,250,161,22,66,245,146,162,65,108,110,122,22,66,30,190,162,65,108,219,81,22,66,70,
229,162,65,108,90,40,22,66,84,8,163,65,108,7,254,21,66,48,39,163,65,108,133,235,21,66,50,51,163,65,108,133,235,21,66,50,51,163,65,108,133,235,21,66,50,51,163,65,108,253,169,21,66,202,91,163,65,108,135,103,21,66,199,125,163,65,108,76,36,21,66,21,153,163,
65,108,121,224,20,66,162,173,163,65,108,55,156,20,66,97,187,163,65,108,180,87,20,66,73,194,163,65,108,235,81,20,66,142,194,163,65,108,235,81,20,66,142,194,163,65,108,133,235,19,66,142,194,163,65,108,132,235,19,66,142,194,163,65,108,71,111,19,66,74,207,
163,65,108,224,242,18,66,151,207,163,65,108,159,118,18,66,116,195,163,65,108,164,112,18,66,142,194,163,65,108,164,112,18,66,142,194,163,65,108,62,10,18,66,142,194,163,65,108,62,10,18,66,142,194,163,65,108,23,216,17,66,5,174,163,65,108,124,165,17,66,134,
158,163,65,108,142,114,17,66,26,148,163,65,108,110,63,17,66,201,142,163,65,108,60,12,17,66,150,142,163,65,108,26,217,16,66,130,147,163,65,108,39,166,16,66,136,157,163,65,108,132,115,16,66,162,172,163,65,108,83,65,16,66,200,192,163,65,108,114,61,16,66,
142,194,163,65,108,113,61,16,66,142,194,163,65,108,52,51,15,66,193,245,164,65,108,52,51,15,66,193,245,164,65,108,203,224,14,66,61,126,165,65,108,230,145,14,66,201,14,166,65,108,236,81,14,66,91,143,166,65,108,236,81,14,66,91,143,166,65,98,226,122,13,66,
245,40,168,65,21,174,12,66,30,133,169,65,134,235,11,66,204,204,170,65,108,11,215,9,66,122,20,174,65,108,174,71,255,65,102,102,186,65,108,174,71,255,65,102,102,186,65,108,111,139,250,65,57,247,187,65,108,171,188,245,65,246,74,189,65,108,119,222,240,65,
196,96,190,65,108,133,235,239,65,92,143,190,65,108,133,235,239,65,92,143,190,65,108,134,235,239,65,92,143,190,65,108,12,26,235,65,206,114,191,65,108,192,62,230,65,82,24,192,65,108,187,92,225,65,124,127,192,65,108,21,174,221,65,214,163,192,65,108,20,174,
221,65,215,163,192,65,108,10,215,219,65,215,163,192,65,108,10,215,219,65,215,163,192,65,108,64,188,217,65,112,134,192,65,108,155,163,215,65,38,78,192,65,108,113,142,213,65,28,251,191,65,108,24,126,211,65,134,141,191,65,108,227,115,209,65,172,5,191,65,
108,30,113,207,65,227,99,190,65,108,21,119,205,65,148,168,189,65,108,10,135,203,65,54,212,188,65,108,58,162,201,65,82,231,187,65,108,41,92,201,65,143,194,187,65,108,41,92,201,65,143,194,187,65,108,41,92,201,65,143,194,187,65,108,244,223,199,65,0,20,186,
65,108,178,78,198,65,252,120,184,65,108,103,169,196,65,137,242,182,65,108,30,241,194,65,161,129,181,65,108,243,38,193,65,49,39,180,65,108,9,76,191,65,21,228,178,65,108,174,71,191,65,71,225,178,65,108,174,71,191,65,71,225,178,65,108,174,71,191,65,71,225,
178,65,108,248,166,190,65,16,135,178,65,108,248,10,190,65,237,36,178,65,108,17,116,189,65,30,187,177,65,108,165,226,188,65,230,73,177,65,108,15,87,188,65,142,209,176,65,108,170,209,187,65,98,82,176,65,108,41,92,187,65,10,215,175,65,108,41,92,187,65,10,
215,175,65,98,72,225,186,65,194,245,174,65,236,81,178,65,123,20,174,65,246,40,178,65,164,112,173,65,108,246,40,178,65,164,112,173,65,108,62,32,178,65,159,10,173,65,108,163,28,178,65,75,164,172,65,108,39,30,178,65,234,61,172,65,108,199,36,178,65,190,215,
171,65,108,246,40,178,65,20,174,171,65,108,246,40,178,65,21,174,171,65,108,246,40,178,65,21,174,171,65,108,190,28,178,65,162,7,171,65,108,221,24,178,65,201,96,170,65,108,83,29,178,65,243,185,169,65,108,31,42,178,65,139,19,169,65,108,55,63,178,65,253,
109,168,65,108,236,81,178,65,0,0,168,65,108,236,81,178,65,0,0,168,65,99,109,72,225,188,65,62,10,141,66,108,72,225,188,65,62,10,141,66,108,164,89,188,65,206,127,141,66,108,172,186,187,65,135,243,141,66,108,195,4,187,65,30,101,142,66,108,95,56,186,65,75,
212,142,66,108,123,20,186,65,103,230,142,66,108,123,20,186,65,103,230,142,66,108,123,20,186,65,103,230,142,66,108,246,45,185,65,183,79,143,66,108,173,50,184,65,5,182,143,66,108,64,35,183,65,14,25,144,66,108,94,0,182,65,147,120,144,66,108,192,202,180,
65,87,212,144,66,108,45,131,179,65,31,44,145,66,108,118,42,178,65,179,127,145,66,108,120,193,176,65,222,206,145,66,108,26,73,175,65,109,25,146,66,108,76,194,173,65,49,95,146,66,108,9,46,172,65,252,159,146,66,108,123,20,172,65,216,163,146,66,108,123,20,
172,65,216,163,146,66,108,123,20,172,65,216,163,146,66,108,116,103,170,65,77,224,146,66,108,225,174,168,65,83,23,147,66,108,218,235,166,65,198,72,147,66,108,128,31,165,65,135,116,147,66,108,251,74,163,65,121,154,147,66,108,118,111,161,65,132,186,147,
66,108,33,142,159,65,148,212,147,66,108,48,168,157,65,152,232,147,66,108,218,190,155,65,131,246,147,66,108,89,211,153,65,76,254,147,66,108,0,0,152,65,0,0,148,66,108,0,0,152,65,0,0,148,66,108,0,0,152,65,0,0,148,66,108,134,101,148,65,24,227,147,66,108,
250,209,144,65,179,186,147,66,108,166,71,141,65,235,134,147,66,108,207,200,137,65,224,71,147,66,108,176,87,134,65,187,253,146,66,108,126,246,130,65,171,168,146,66,108,196,78,127,65,231,72,146,66,108,174,71,125,65,246,40,146,66,108,174,71,125,65,246,40,
146,66,108,174,71,109,65,10,87,145,66,108,173,71,109,65,10,87,145,66,108,223,181,81,65,238,44,144,66,108,178,181,53,65,72,47,143,66,108,16,89,25,65,189,94,142,66,108,92,143,22,65,205,76,142,66,108,92,143,22,65,205,76,142,66,98,41,92,3,65,144,194,141,
66,61,10,223,64,51,51,141,66,194,245,184,64,225,122,140,66,108,123,20,150,64,205,204,139,66,98,205,204,132,64,164,112,139,66,62,10,103,64,154,25,139,66,226,122,68,64,236,209,138,66,108,32,133,43,64,154,153,138,66,108,33,133,43,64,154,153,138,66,108,20,
243,30,64,149,123,138,66,108,14,149,18,64,147,88,138,66,108,250,114,6,64,171,48,138,66,108,57,41,245,63,245,3,138,66,108,51,51,243,63,0,0,138,66,108,51,51,243,63,0,0,138,66,108,51,51,243,63,0,0,138,66,108,70,7,234,63,228,240,137,66,108,156,14,225,63,
248,223,137,66,108,244,78,216,63,69,205,137,66,108,228,205,207,63,218,184,137,66,108,225,144,199,63,193,162,137,66,108,46,157,191,63,10,139,137,66,108,226,247,183,63,195,113,137,66,108,225,165,176,63,253,86,137,66,108,219,171,169,63,201,58,137,66,108,
68,14,163,63,57,29,137,66,108,91,209,156,63,96,254,136,66,108,29,249,150,63,82,222,136,66,108,51,51,147,63,174,199,136,66,108,51,51,147,63,174,199,136,66,108,51,51,147,63,174,199,136,66,108,24,134,143,63,103,170,136,66,108,210,55,140,63,108,140,136,66,
108,127,74,137,63,210,109,136,66,108,253,191,134,63,172,78,136,66,108,238,153,132,63,14,47,136,66,108,177,217,130,63,12,15,136,66,108,101,128,129,63,187,238,135,66,108,231,142,128,63,47,206,135,66,108,210,5,128,63,125,173,135,66,108,250,202,127,63,187,
140,135,66,108,254,255,127,63,225,122,135,66,108,0,0,128,63,225,122,135,66,108,0,0,128,63,225,122,135,66,108,148,178,128,63,31,66,135,66,108,124,26,130,63,147,9,135,66,108,208,54,132,63,97,209,134,66,108,56,6,135,63,173,153,134,66,108,230,134,138,63,
154,98,134,66,108,158,182,142,63,77,44,134,66,108,178,146,147,63,231,246,133,66,108,144,194,149,63,70,225,133,66,108,143,194,149,63,71,225,133,66,108,144,194,149,63,71,225,133,66,108,132,92,170,63,249,21,133,66,108,40,122,193,63,11,79,132,66,108,36,133,
203,63,0,0,132,66,108,31,133,203,63,0,0,132,66,98,164,112,221,63,164,112,131,66,41,92,239,63,72,225,130,66,82,184,254,63,174,71,130,66,108,84,184,254,63,174,71,130,66,108,24,127,7,64,127,136,129,66,108,170,109,14,64,75,198,128,66,108,106,35,20,64,145,
1,128,66,108,180,156,24,64,153,117,126,66,108,172,214,27,64,252,228,124,66,108,64,207,29,64,75,82,123,66,108,46,133,30,64,135,190,121,66,108,0,248,29,64,179,42,120,66,108,206,204,28,64,61,10,119,66,108,205,204,28,64,61,10,119,66,98,205,204,28,64,215,
163,116,66,62,10,23,64,112,61,114,66,92,143,18,64,10,215,111,66,98,122,20,14,64,164,112,109,66,31,133,11,64,184,30,108,66,153,153,9,64,112,61,106,66,108,154,153,9,64,112,61,106,66,108,244,238,7,64,219,62,105,66,108,110,16,7,64,67,63,104,66,108,146,254,
6,64,74,63,103,66,108,110,185,7,64,149,63,102,66,108,136,64,9,64,199,64,101,66,108,154,153,9,64,122,20,101,66,108,153,153,9,64,122,20,101,66,108,153,153,9,64,122,20,101,66,108,161,19,11,64,18,171,100,66,108,122,225,12,64,251,66,100,66,108,252,1,15,64,
118,220,99,66,108,204,115,17,64,197,119,99,66,108,88,53,20,64,41,21,99,66,108,221,68,23,64,224,180,98,66,108,102,160,26,64,41,87,98,66,108,206,69,30,64,63,252,97,66,108,190,50,34,64,93,164,97,66,108,180,100,38,64,186,79,97,66,108,153,153,41,64,122,20,
97,66,108,153,153,41,64,122,20,97,66,108,152,153,41,64,122,20,97,66,108,71,66,46,64,253,213,96,66,108,112,27,51,64,78,155,96,66,108,250,33,56,64,146,100,96,66,108,173,82,61,64,236,49,96,66,108,56,170,66,64,125,3,96,66,108,46,37,72,64,98,217,95,66,108,
15,192,77,64,183,179,95,66,108,68,119,83,64,147,146,95,66,108,38,71,89,64,12,118,95,66,108,251,43,95,64,52,94,95,66,108,254,33,101,64,26,75,95,66,108,102,102,102,64,173,71,95,66,108,102,102,102,64,173,71,95,66,108,102,102,102,64,173,71,95,66,108,107,
218,112,64,170,38,95,66,108,126,101,123,64,13,14,95,66,108,112,0,131,64,231,253,94,66,108,228,82,136,64,65,246,94,66,108,30,133,139,64,193,245,94,66,108,30,133,139,64,193,245,94,66,108,20,174,167,64,193,245,94,66,98,174,71,177,64,193,245,94,66,71,225,
186,64,193,245,94,66,204,204,196,64,193,245,94,66,108,204,204,196,64,193,245,94,66,108,2,38,202,64,202,234,94,66,108,31,121,207,64,73,215,94,66,108,187,194,212,64,74,187,94,66,108,117,255,217,64,223,150,94,66,108,242,43,223,64,31,106,94,66,108,227,68,
228,64,39,53,94,66,108,5,71,233,64,26,248,93,66,108,35,47,238,64,29,179,93,66,108,26,250,242,64,93,102,93,66,108,245,40,244,64,234,81,93,66,108,245,40,244,64,234,81,93,66,108,244,40,244,64,234,81,93,66,108,41,113,248,64,214,255,92,66,108,45,151,252,64,
4,167,92,66,108,45,76,0,65,171,71,92,66,108,16,57,2,65,9,226,91,66,108,4,17,4,65,94,118,91,66,108,218,210,5,65,241,4,91,66,108,115,125,7,65,9,142,90,66,108,191,15,9,65,243,17,90,66,108,187,136,10,65,254,144,89,66,108,51,51,11,65,234,81,89,66,108,51,51,
11,65,234,81,89,66,108,51,51,11,65,234,81,89,66,108,72,97,16,65,234,104,87,66,108,244,43,21,65,245,111,85,66,108,164,112,21,65,234,81,85,66,108,164,112,21,65,234,81,85,66,108,164,112,21,65,254,255,84,66,108,164,112,21,65,254,255,84,66,108,218,56,24,65,
213,189,83,66,108,149,64,27,65,249,132,82,66,108,227,133,30,65,51,86,81,66,108,31,133,31,65,254,255,80,66,108,31,133,31,65,254,255,80,66,108,31,133,31,65,254,255,80,66,108,219,137,32,65,8,177,80,66,108,12,158,33,65,110,101,80,66,108,2,193,34,65,95,29,
80,66,108,2,242,35,65,9,217,79,66,108,74,48,37,65,153,152,79,66,108,15,123,38,65,56,92,79,66,108,123,209,39,65,13,36,79,66,108,181,50,41,65,58,240,78,66,108,218,157,42,65,226,192,78,66,108,2,18,44,65,35,150,78,66,108,236,81,44,65,90,143,78,66,108,236,
81,44,65,90,143,78,66,108,236,81,44,65,90,143,78,66,108,236,81,44,65,90,143,78,66,108,183,159,45,65,48,112,78,66,108,83,243,46,65,59,85,78,66,108,229,75,48,65,141,62,78,66,108,146,168,49,65,52,44,78,66,108,123,8,51,65,61,30,78,66,108,190,106,52,65,175,
20,78,66,108,120,206,53,65,146,15,78,66,108,198,50,55,65,233,14,78,66,108,196,150,56,65,179,18,78,66,108,142,249,57,65,239,26,78,66,108,65,90,59,65,151,39,78,66,108,236,81,60,65,49,51,78,66,108,236,81,60,65,49,51,78,66,108,236,81,60,65,49,51,78,66,108,
197,59,62,65,211,75,78,66,108,21,32,64,65,140,106,78,66,108,166,253,65,65,72,143,78,66,108,70,211,67,65,241,185,78,66,108,200,159,69,65,105,234,78,66,108,6,98,71,65,147,32,79,66,108,224,24,73,65,76,92,79,66,108,62,195,74,65,110,157,79,66,108,236,81,76,
65,69,225,79,66,108,236,81,76,65,69,225,79,66,108,236,81,76,65,69,225,79,66,108,202,130,80,65,229,183,80,66,108,104,135,84,65,168,155,81,66,108,54,93,88,65,252,139,82,66,108,188,1,92,65,71,136,83,66,108,169,114,95,65,233,143,84,66,108,200,173,98,65,56,
162,85,66,108,6,177,101,65,133,190,86,66,108,113,61,102,65,192,245,86,66,108,113,61,102,65,192,245,86,66,98,82,184,110,65,8,215,89,66,113,61,118,65,151,153,92,66,144,194,125,65,172,71,95,66,98,246,40,132,65,172,71,99,66,62,10,137,65,131,235,102,66,174,
71,141,65,90,143,106,66,108,92,143,146,65,182,30,111,66,108,92,143,146,65,181,30,111,66,108,145,138,152,65,132,52,116,66,108,253,5,159,65,110,34,121,66,108,11,215,161,65,182,30,123,66,108,10,215,161,65,182,30,123,66,98,102,102,164,65,8,215,124,66,184,
30,167,65,28,133,126,66,10,215,169,65,122,20,128,66,98,92,143,172,65,102,230,128,66,20,174,173,65,204,76,129,66,153,153,175,65,102,230,129,66,108,163,112,177,65,0,128,130,66,108,163,112,177,65,0,128,130,66,108,225,92,179,65,173,35,131,66,108,201,39,181,
65,77,205,131,66,108,52,208,182,65,114,124,132,66,108,20,85,184,65,173,48,133,66,108,112,181,185,65,138,233,133,66,108,102,240,186,65,147,166,134,66,108,45,5,188,65,79,103,135,66,108,102,102,188,65,51,179,135,66,108,102,102,188,65,51,179,135,66,108,102,
102,188,65,51,179,135,66,108,37,240,188,65,228,53,136,66,108,151,95,189,65,36,186,136,66,108,116,180,189,65,159,63,137,66,108,136,238,189,65,254,197,137,66,108,172,13,190,65,236,76,138,66,108,204,17,190,65,18,212,138,66,108,231,250,189,65,26,91,139,66,
108,10,201,189,65,174,225,139,66,108,85,124,189,65,120,103,140,66,108,250,20,189,65,33,236,140,66,108,72,225,188,65,215,35,141,66,108,72,225,188,65,215,35,141,66,99,109,195,245,16,66,62,10,132,66,108,195,245,16,66,62,10,132,66,108,62,132,14,66,180,163,
132,66,108,43,4,12,66,87,45,133,66,108,34,119,9,66,208,166,133,66,108,199,222,6,66,208,15,134,66,108,192,60,4,66,20,104,134,66,108,191,146,1,66,100,175,134,66,108,238,196,253,65,146,229,134,66,108,66,91,248,65,123,10,135,66,108,239,235,242,65,9,30,135,
66,108,114,122,237,65,46,32,135,66,108,68,10,232,65,232,16,135,66,108,225,158,226,65,67,240,134,66,108,193,59,221,65,82,190,134,66,108,86,228,215,65,54,123,134,66,108,11,156,210,65,26,39,134,66,108,66,102,205,65,51,194,133,66,108,79,70,200,65,194,76,
133,66,108,122,63,195,65,18,199,132,66,108,0,0,192,65,102,102,132,66,108,0,0,192,65,102,102,132,66,108,0,0,192,65,102,102,132,66,108,204,169,189,65,46,102,131,66,108,30,33,187,65,193,109,130,66,108,148,103,184,65,190,125,129,66,108,0,0,184,65,41,92,129,
66,108,0,0,184,65,41,92,129,66,98,164,112,181,65,0,128,128,66,205,204,178,65,41,92,127,66,0,0,176,65,82,184,125,66,98,51,51,173,65,123,20,124,66,205,204,170,65,31,133,122,66,0,0,168,65,10,215,120,66,108,255,255,167,65,10,215,120,66,108,246,128,161,65,
229,15,116,66,108,69,126,155,65,185,32,111,66,108,176,71,153,65,248,40,109,66,108,174,71,153,65,246,40,109,66,98,31,133,151,65,154,153,107,66,143,194,149,65,123,20,106,66,133,235,147,65,92,143,104,66,98,194,245,140,65,20,174,98,66,205,204,132,65,92,143,
92,66,133,235,117,65,143,194,85,66,108,134,235,117,65,142,194,85,66,108,12,45,116,65,236,136,81,66,108,94,71,115,65,15,75,77,66,108,16,59,115,65,175,11,73,66,108,40,8,116,65,132,205,68,66,108,206,204,116,65,91,143,66,66,108,205,204,116,65,92,143,66,66,
108,206,204,116,65,92,143,66,66,108,162,131,119,65,28,117,61,66,108,188,62,123,65,44,101,56,66,108,184,251,127,65,202,98,51,66,108,199,219,130,65,43,113,46,66,108,75,55,134,65,119,147,41,66,108,63,14,138,65,204,204,36,66,108,42,92,139,65,235,81,35,66,
108,41,92,139,65,235,81,35,66,108,43,92,139,65,235,81,35,66,108,19,98,144,65,251,247,29,66,108,79,239,149,65,228,191,24,66,108,83,0,156,65,252,172,19,66,108,124,20,160,65,92,143,16,66,108,123,20,160,65,92,143,16,66,108,123,20,160,65,91,143,16,66,108,
38,214,159,65,90,42,15,66,108,148,187,159,65,60,196,13,66,108,216,196,159,65,230,93,12,66,108,234,241,159,65,63,248,10,66,108,173,66,160,65,42,148,9,66,108,239,182,160,65,139,50,8,66,108,100,78,161,65,70,212,6,66,108,172,8,162,65,58,122,5,66,108,123,
20,162,65,101,102,5,66,108,123,20,162,65,102,102,5,66,108,124,20,162,65,102,102,5,66,108,4,65,164,65,238,173,2,66,108,120,178,166,65,61,4,0,66,108,72,103,169,65,14,214,250,65,108,184,93,172,65,236,199,245,65,108,229,147,175,65,80,225,240,65,108,190,7,
179,65,93,37,236,65,108,124,20,180,65,204,204,234,65,108,123,20,180,65,204,204,234,65,108,123,20,180,65,204,204,234,65,108,4,222,181,65,38,136,232,65,108,245,137,183,65,92,45,230,65,108,61,23,185,65,239,189,227,65,108,221,132,186,65,111,59,225,65,108,
236,209,187,65,118,167,222,65,108,148,253,188,65,170,3,220,65,108,22,7,190,65,190,81,217,65,108,225,122,190,65,0,0,216,65,108,225,122,190,65,255,255,215,65,108,225,122,190,65,255,255,215,65,108,158,52,191,65,193,238,211,65,108,21,186,191,65,135,213,207,
65,108,241,10,192,65,241,182,203,65,108,254,38,192,65,162,149,199,65,108,123,20,192,65,255,255,195,65,108,123,20,192,65,255,255,195,65,98,123,20,192,65,204,204,194,65,123,20,192,65,19,174,193,65,123,20,192,65,224,122,192,65,108,246,40,194,65,255,255,
193,65,108,62,10,195,65,224,122,194,65,108,113,61,196,65,132,235,195,65,108,41,92,199,65,255,255,199,65,108,40,92,199,65,254,255,199,65,108,15,13,201,65,84,102,202,65,108,32,220,202,65,67,182,204,65,108,49,200,204,65,80,238,206,65,108,9,208,206,65,14,
13,209,65,108,91,242,208,65,36,17,211,65,108,201,45,211,65,70,249,212,65,108,225,122,212,65,0,0,214,65,108,225,122,212,65,255,255,213,65,108,225,122,212,65,255,255,213,65,108,48,6,214,65,131,7,215,65,108,43,158,215,65,240,250,215,65,108,207,65,217,65,
172,217,216,65,108,14,240,218,65,40,163,217,65,108,213,167,220,65,226,86,218,65,108,11,104,222,65,103,244,218,65,108,145,47,224,65,84,123,219,65,108,68,253,225,65,81,235,219,65,108,252,207,227,65,23,68,220,65,108,142,166,229,65,110,133,220,65,108,72,
225,230,65,214,163,220,65,108,71,225,230,65,214,163,220,65,108,40,92,235,65,214,163,220,65,108,39,92,235,65,214,163,220,65,108,228,65,238,65,94,134,220,65,108,58,37,241,65,220,67,220,65,108,81,4,244,65,125,220,219,65,108,82,221,246,65,130,80,219,65,108,
107,174,249,65,68,160,218,65,108,122,20,252,65,132,235,217,65,108,122,20,252,65,132,235,217,65,108,122,20,252,65,132,235,217,65,108,220,112,255,65,50,207,216,65,108,251,94,1,66,60,136,215,65,108,213,252,2,66,114,23,214,65,108,243,144,4,66,191,125,212,
65,108,83,26,6,66,42,188,210,65,108,143,194,6,66,132,235,209,65,108,143,194,6,66,132,235,209,65,108,143,194,6,66,132,235,209,65,108,32,42,9,66,202,144,206,65,108,118,123,11,66,156,249,202,65,108,184,30,12,66,132,235,201,65,108,184,30,12,66,132,235,201,
65,108,184,30,12,66,132,235,201,65,108,146,80,13,66,58,39,200,65,108,88,141,14,66,19,130,198,65,108,62,212,15,66,30,253,196,65,108,117,36,17,66,82,153,195,65,108,35,125,18,66,147,87,194,65,108,110,221,19,66,175,56,193,65,108,0,0,20,66,184,30,193,65,108,
0,0,20,66,184,30,193,65,108,61,10,21,66,102,102,192,65,108,61,10,21,66,102,102,192,65,108,70,248,21,66,20,200,191,65,108,14,226,22,66,42,18,191,65,108,215,163,23,66,102,102,190,65,108,215,163,23,66,102,102,190,65,108,123,20,24,66,133,235,189,65,98,123,
20,25,66,123,20,194,65,10,215,25,66,102,102,198,65,143,194,26,66,92,143,202,65,98,194,245,28,66,194,245,212,65,10,215,31,66,82,184,222,65,112,61,34,66,184,30,233,65,108,112,61,34,66,184,30,233,65,108,176,214,35,66,208,115,240,65,108,132,64,37,66,121,
239,247,65,108,6,122,38,66,231,140,255,65,108,108,130,39,66,158,163,3,66,108,14,89,40,66,195,140,7,66,108,132,235,40,66,0,0,11,66,108,132,235,40,66,0,0,11,66,108,132,235,40,66,0,0,11,66,108,198,219,42,66,186,22,13,66,108,176,176,44,66,150,69,15,66,108,
21,105,46,66,48,139,17,66,108,220,3,48,66,17,230,19,66,108,254,127,49,66,186,84,22,66,108,136,220,50,66,155,213,24,66,108,224,122,51,66,123,20,26,66,108,224,122,51,66,123,20,26,66,98,173,71,59,66,123,20,42,66,244,40,59,66,0,0,61,66,122,20,57,66,144,194,
78,66,108,122,20,57,66,144,194,78,66,108,50,75,56,66,209,154,84,66,108,99,55,55,66,35,103,90,66,108,50,51,55,66,226,122,90,66,108,50,51,55,66,226,122,90,66,108,224,122,52,66,124,20,90,66,108,214,163,50,66,206,204,89,66,108,214,163,50,66,206,204,89,66,
108,233,168,49,66,57,154,89,66,108,197,171,48,66,62,116,89,66,108,12,173,47,66,246,90,89,66,108,97,173,46,66,114,78,89,66,108,104,173,45,66,185,78,89,66,108,234,81,45,66,237,81,89,66,108,234,81,45,66,237,81,89,66,108,234,81,45,66,237,81,89,66,108,30,
199,44,66,42,93,89,66,108,15,61,44,66,83,111,89,66,108,20,180,43,66,92,136,89,66,108,133,44,43,66,55,168,89,66,108,185,166,42,66,205,206,89,66,108,6,35,42,66,7,252,89,66,108,192,161,41,66,200,47,90,66,108,57,35,41,66,238,105,90,66,108,194,167,40,66,84,
170,90,66,108,171,47,40,66,210,240,90,66,108,65,187,39,66,57,61,91,66,108,205,74,39,66,90,143,91,66,108,60,10,39,66,145,194,91,66,108,60,10,39,66,145,194,91,66,108,60,10,39,66,145,194,91,66,108,5,169,38,66,167,34,92,66,108,186,76,38,66,123,135,92,66,
108,150,245,37,66,203,240,92,66,108,210,163,37,66,85,94,93,66,108,162,87,37,66,210,207,93,66,108,54,17,37,66,249,68,94,66,108,187,208,36,66,127,189,94,66,108,91,150,36,66,25,57,95,66,108,59,98,36,66,117,183,95,66,108,125,52,36,66,68,56,96,66,108,61,13,
36,66,51,187,96,66,108,150,236,35,66,238,63,97,66,108,154,210,35,66,33,198,97,66,108,142,194,35,66,53,51,98,66,108,142,194,35,66,53,51,98,66,108,142,194,35,66,53,51,98,66,108,92,168,35,66,74,140,99,66,108,114,159,35,66,64,230,100,66,108,213,167,35,66,
57,64,102,66,108,128,193,35,66,89,153,103,66,108,142,194,35,66,217,163,103,66,108,142,194,35,66,217,163,103,66,108,143,194,35,66,217,163,103,66,108,6,30,36,66,46,83,111,66,108,12,23,36,66,160,4,119,66,108,1,0,36,66,226,122,121,66,108,0,0,36,66,225,122,
121,66,108,0,0,36,66,226,122,121,66,108,227,173,32,66,7,174,124,66,108,229,51,29,66,169,181,127,66,108,64,148,25,66,236,71,129,66,108,70,209,21,66,97,157,130,66,108,94,237,17,66,88,218,131,66,108,196,245,16,66,215,35,132,66,108,195,245,16,66,215,35,132,
66,99,109,195,245,120,66,123,148,133,66,108,195,245,120,66,123,148,133,66,108,52,162,120,66,24,248,133,66,108,202,68,120,66,127,89,134,66,108,194,221,119,66,112,184,134,66,108,93,109,119,66,177,20,135,66,108,228,243,118,66,5,110,135,66,108,163,113,118,
66,51,196,135,66,108,246,40,118,66,164,240,135,66,108,246,40,118,66,164,240,135,66,108,246,40,118,66,164,240,135,66,108,172,26,117,66,19,122,136,66,108,252,254,115,66,148,252,136,66,108,155,214,114,66,213,119,137,66,108,70,162,113,66,135,235,137,66,108,
196,98,112,66,95,87,138,66,108,225,24,111,66,24,187,138,66,108,111,197,109,66,116,22,139,66,108,72,105,108,66,54,105,139,66,108,174,71,108,66,164,112,139,66,108,174,71,108,66,164,112,139,66,108,82,184,102,66,236,209,140,66,108,82,184,102,66,236,209,140,
66,108,243,156,97,66,85,18,142,66,108,61,163,92,66,3,115,143,66,108,195,245,89,66,144,66,144,66,108,195,245,89,66,144,66,144,66,108,194,245,89,66,144,66,144,66,108,178,214,86,66,228,87,145,66,108,92,212,83,66,215,128,146,66,108,169,240,80,66,172,188,
147,66,108,61,10,79,66,185,158,148,66,108,62,10,79,66,185,158,148,66,108,246,40,77,66,62,138,149,66,108,246,40,77,66,62,138,149,66,108,102,6,75,66,243,151,150,66,108,142,201,72,66,169,151,151,66,108,222,115,70,66,188,136,152,66,108,174,71,70,66,154,153,
152,66,108,174,71,70,66,154,153,152,66,108,174,71,70,66,154,153,152,66,108,26,68,69,66,68,246,152,66,108,150,55,68,66,83,76,153,66,108,207,34,67,66,144,155,153,66,108,115,6,66,66,202,227,153,66,108,59,227,64,66,210,36,154,66,108,224,185,63,66,125,94,
154,66,108,32,139,62,66,168,144,154,66,108,189,87,61,66,50,187,154,66,108,124,32,60,66,0,222,154,66,108,235,81,59,66,164,240,154,66,108,235,81,59,66,164,240,154,66,108,235,81,59,66,164,240,154,66,108,56,48,58,66,38,2,155,66,108,33,13,57,66,101,12,155,
66,108,133,235,55,66,92,15,155,66,108,133,235,55,66,92,15,155,66,108,41,92,55,66,92,15,155,66,108,41,92,55,66,92,15,155,66,108,33,33,54,66,44,8,155,66,108,54,231,52,66,31,249,154,66,108,102,102,52,66,164,240,154,66,108,102,102,52,66,164,240,154,66,108,
61,10,52,66,164,240,154,66,108,61,10,52,66,164,240,154,66,108,160,162,50,66,224,210,154,66,108,112,62,49,66,41,172,154,66,108,145,222,47,66,152,124,154,66,108,227,131,46,66,76,68,154,66,108,69,47,45,66,103,3,154,66,108,184,30,45,66,0,0,154,66,108,184,
30,45,66,0,0,154,66,108,184,30,45,66,0,0,154,66,108,43,83,44,66,196,214,153,66,108,254,139,43,66,127,168,153,66,108,176,201,42,66,78,117,153,66,108,191,12,42,66,82,61,153,66,108,163,85,41,66,176,0,153,66,108,209,164,40,66,142,191,152,66,108,186,250,39,
66,21,122,152,66,108,204,87,39,66,115,48,152,66,108,110,188,38,66,213,226,151,66,108,3,41,38,66,111,145,151,66,108,235,157,37,66,116,60,151,66,108,184,30,37,66,103,230,150,66,108,184,30,37,66,102,230,150,66,108,184,30,37,66,102,230,150,66,108,10,178,
36,66,161,121,150,66,108,94,80,36,66,72,10,150,66,108,243,249,35,66,161,152,149,66,108,255,174,35,66,246,36,149,66,108,180,111,35,66,144,175,148,66,108,56,60,35,66,187,56,148,66,108,174,20,35,66,195,192,147,66,108,47,249,34,66,244,71,147,66,108,204,233,
34,66,156,206,146,66,108,143,230,34,66,8,85,146,66,108,133,235,34,66,0,0,146,66,108,133,235,34,66,0,0,146,66,98,133,235,34,66,154,25,145,66,133,235,34,66,51,51,144,66,51,51,35,66,205,76,143,66,98,153,153,35,66,21,46,141,66,41,92,36,66,92,15,139,66,184,
30,37,66,225,250,136,66,98,184,30,38,66,51,51,134,66,71,225,38,66,112,189,131,66,164,112,39,66,225,122,129,66,98,1,0,40,66,164,112,126,66,246,40,40,66,174,71,122,66,51,51,40,66,20,174,117,66,98,112,61,40,66,122,20,113,66,51,51,40,66,40,92,108,66,82,184,
39,66,30,133,103,66,108,82,184,39,66,30,133,103,66,108,137,162,39,66,184,82,102,66,108,24,156,39,66,158,31,101,66,108,1,165,39,66,148,236,99,66,108,82,184,39,66,132,235,98,66,108,82,184,39,66,132,235,98,66,108,82,184,39,66,132,235,98,66,108,63,195,39,
66,193,151,98,66,108,88,210,39,66,165,68,98,66,108,148,229,39,66,100,242,97,66,108,230,252,39,66,52,161,97,66,108,64,24,40,66,72,81,97,66,108,143,55,40,66,212,2,97,66,108,192,90,40,66,10,182,96,66,108,188,129,40,66,26,107,96,66,108,107,172,40,66,53,34,
96,66,108,176,218,40,66,137,219,95,66,108,111,12,41,66,68,151,95,66,108,136,65,41,66,146,85,95,66,108,216,121,41,66,155,22,95,66,108,215,163,41,66,132,235,94,66,108,215,163,41,66,132,235,94,66,108,215,163,41,66,132,235,94,66,108,54,233,41,66,246,182,
94,66,108,30,49,42,66,240,133,94,66,108,100,123,42,66,145,88,94,66,108,214,199,42,66,248,46,94,66,108,67,22,43,66,62,9,94,66,108,123,102,43,66,123,231,93,66,108,72,184,43,66,197,201,93,66,108,120,11,44,66,48,176,93,66,108,212,95,44,66,203,154,93,66,108,
39,181,44,66,164,137,93,66,108,58,11,45,66,199,124,93,66,108,214,97,45,66,59,116,93,66,108,215,163,45,66,163,112,93,66,108,215,163,45,66,163,112,93,66,108,41,92,46,66,163,112,93,66,108,41,92,46,66,162,112,93,66,108,174,58,47,66,124,121,93,66,108,123,
24,48,66,113,141,93,66,108,2,245,48,66,118,172,93,66,108,181,207,49,66,118,214,93,66,108,0,0,50,66,70,225,93,66,108,0,0,50,66,71,225,93,66,108,184,30,52,66,51,51,94,66,108,235,81,54,66,31,133,94,66,98,245,40,56,66,205,204,94,66,255,255,57,66,185,30,95,
66,204,204,59,66,92,143,95,66,98,81,184,60,66,205,204,95,66,214,163,61,66,123,20,96,66,204,204,62,66,164,112,96,66,98,194,245,63,66,205,204,96,66,9,215,64,66,123,20,97,66,9,215,65,66,236,81,97,66,108,234,81,66,66,236,81,97,66,108,234,81,66,66,236,81,
97,66,108,117,158,66,66,220,198,97,66,108,191,240,66,66,212,55,98,66,108,149,72,67,66,138,164,98,66,108,189,165,67,66,186,12,99,66,108,253,7,68,66,32,112,99,66,108,21,111,68,66,126,206,99,66,108,195,218,68,66,150,39,100,66,108,195,74,69,66,49,123,100,
66,108,205,190,69,66,23,201,100,66,108,150,54,70,66,24,17,101,66,108,211,177,70,66,5,83,101,66,108,51,48,71,66,180,142,101,66,108,102,177,71,66,0,196,101,66,108,26,53,72,66,197,242,101,66,108,214,163,72,66,123,20,102,66,108,214,163,72,66,123,20,102,66,
108,214,163,72,66,123,20,102,66,108,164,86,73,66,57,67,102,66,108,143,11,74,66,247,104,102,66,108,35,194,74,66,159,133,102,66,108,235,121,75,66,30,153,102,66,108,114,50,76,66,102,163,102,66,108,65,235,76,66,115,164,102,66,108,226,163,77,66,67,156,102,
66,108,224,91,78,66,219,138,102,66,108,196,18,79,66,71,112,102,66,108,26,200,79,66,151,76,102,66,108,109,123,80,66,226,31,102,66,108,214,163,80,66,123,20,102,66,108,214,163,80,66,123,20,102,66,108,214,163,80,66,123,20,102,66,108,81,160,81,66,45,204,101,
66,108,222,152,82,66,87,119,101,66,108,221,140,83,66,48,22,101,66,108,180,123,84,66,247,168,100,66,108,200,100,85,66,240,47,100,66,108,134,71,86,66,106,171,99,66,108,91,35,87,66,186,27,99,66,108,188,247,87,66,58,129,98,66,108,0,0,88,66,225,122,98,66,
108,0,0,88,66,225,122,98,66,108,0,0,88,66,225,122,98,66,108,82,219,88,66,241,171,97,66,108,7,172,89,66,78,210,96,66,108,205,204,89,66,20,174,96,66,108,205,204,89,66,20,174,96,66,108,195,245,90,66,133,235,96,66,108,185,30,92,66,113,61,97,66,108,185,30,
92,66,113,61,97,66,108,184,156,92,66,21,101,97,66,108,146,24,93,66,248,146,97,66,108,250,145,93,66,254,198,97,66,108,162,8,94,66,4,1,98,66,108,61,124,94,66,230,64,98,66,108,130,236,94,66,122,134,98,66,108,41,89,95,66,149,209,98,66,108,236,193,95,66,5,
34,99,66,108,185,30,96,66,164,112,99,66,108,185,30,96,66,164,112,99,66,108,185,30,96,66,164,112,99,66,108,95,120,96,66,134,218,99,66,108,157,204,96,66,194,72,100,66,108,62,27,97,66,16,187,100,66,108,15,100,97,66,39,49,101,66,108,226,166,97,66,188,170,
101,66,108,140,227,97,66,130,39,102,66,108,124,20,98,66,154,153,102,66,108,124,20,98,66,154,153,102,66,108,124,20,98,66,154,153,102,66,108,122,104,98,66,16,135,103,66,108,126,176,98,66,109,120,104,66,108,92,236,98,66,22,109,105,66,108,236,27,99,66,110,
100,106,66,108,17,63,99,66,216,93,107,66,108,174,71,99,66,21,174,107,66,108,175,71,99,66,21,174,107,66,108,175,71,99,66,185,30,109,66,108,174,71,99,66,185,30,109,66,108,178,86,99,66,218,94,110,66,108,176,117,99,66,212,157,111,66,108,155,153,99,66,155,
153,112,66,108,155,153,99,66,154,153,112,66,108,155,153,99,66,154,153,112,66,108,129,198,99,66,80,85,113,66,108,187,252,99,66,139,14,114,66,108,37,60,100,66,213,196,114,66,108,151,132,100,66,185,119,115,66,108,226,213,100,66,198,38,116,66,108,212,47,
101,66,138,209,116,66,108,49,146,101,66,152,119,117,66,108,188,252,101,66,136,24,118,66,108,48,111,102,66,240,179,118,66,108,67,233,102,66,110,73,119,66,108,124,20,103,66,226,122,119,66,108,124,20,103,66,226,122,119,66,108,125,20,103,66,226,122,119,66,
108,158,190,104,66,123,60,121,66,108,176,126,106,66,56,232,122,66,108,147,83,108,66,7,125,124,66,108,145,194,108,66,11,215,124,66,108,144,194,108,66,11,215,124,66,108,145,194,108,66,11,215,124,66,108,157,241,110,66,234,174,126,66,108,140,55,113,66,33,
53,128,66,108,135,235,114,66,205,204,128,66,108,134,235,114,66,205,204,128,66,108,1,0,116,66,246,40,129,66,108,1,0,116,66,246,40,129,66,108,64,175,116,66,201,97,129,66,108,153,88,117,66,236,158,129,66,108,159,251,117,66,54,224,129,66,108,62,10,118,66,
103,230,129,66,108,62,10,118,66,103,230,129,66,108,62,10,118,66,103,230,129,66,108,72,95,118,66,74,7,130,66,108,238,176,118,66,66,42,130,66,108,252,254,118,66,58,79,130,66,108,62,73,119,66,25,118,130,66,108,133,143,119,66,198,158,130,66,108,166,209,119,
66,40,201,130,66,108,116,15,120,66,36,245,130,66,108,202,72,120,66,157,34,131,66,108,42,92,120,66,52,51,131,66,108,42,92,120,66,52,51,131,66,108,42,92,120,66,52,51,131,66,108,44,133,120,66,116,90,131,66,108,52,170,120,66,174,130,131,66,108,42,203,120,
66,201,171,131,66,108,251,231,120,66,168,213,131,66,108,146,0,121,66,51,0,132,66,108,225,20,121,66,78,43,132,66,108,219,36,121,66,220,86,132,66,108,117,48,121,66,195,130,132,66,108,168,55,121,66,230,174,132,66,108,111,58,121,66,41,219,132,66,108,201,
56,121,66,112,7,133,66,108,182,50,121,66,157,51,133,66,108,58,40,121,66,150,95,133,66,108,93,25,121,66,62,139,133,66,108,61,10,121,66,20,174,133,66,108,61,10,121,66,20,174,133,66,99,101,0,0 };
const uint8 xcode[] = { 110,109,72,225,2,66,41,92,31,64,108,72,225,2,66,40,92,31,64,108,137,147,2,66,16,119,29,64,108,95,68,2,66,188,208,27,64,108,253,243,1,66,63,106,26,64,108,150,162,1,66,123,68,25,64,108,94,80,1,66,46,96,24,64,108,138,253,0,66,233,189,23,64,108,79,170,0,
66,20,94,23,64,108,225,86,0,66,236,64,23,64,108,119,3,0,66,134,102,23,64,108,140,96,255,65,198,206,23,64,108,6,187,254,65,108,121,24,64,108,197,22,254,65,11,102,25,64,108,51,116,253,65,10,148,26,64,108,185,211,252,65,170,2,28,64,108,187,53,252,65,253,
176,29,64,108,20,174,251,65,40,92,31,64,108,21,174,251,65,41,92,31,64,108,21,174,251,65,41,92,31,64,108,73,51,251,65,222,11,33,64,108,242,181,250,65,240,137,34,64,108,96,54,250,65,106,213,35,64,108,229,180,249,65,120,237,36,64,108,212,49,249,65,104,209,
37,64,108,127,173,248,65,166,128,38,64,108,61,40,248,65,196,250,38,64,108,98,162,247,65,115,63,39,64,108,69,28,247,65,134,78,39,64,108,57,150,246,65,246,39,39,64,108,151,16,246,65,217,203,38,64,108,179,139,245,65,107,58,38,64,108,225,7,245,65,10,116,
37,64,108,119,133,244,65,50,121,36,64,108,200,4,244,65,136,74,35,64,108,39,134,243,65,201,232,33,64,108,227,9,243,65,218,84,32,64,108,77,144,242,65,190,143,30,64,108,179,25,242,65,149,154,28,64,108,97,166,241,65,160,118,26,64,108,159,54,241,65,64,37,
24,64,108,183,202,240,65,237,167,21,64,108,236,98,240,65,66,0,19,64,108,129,255,239,65,240,47,16,64,108,182,160,239,65,196,56,13,64,108,42,92,239,65,72,225,10,64,108,42,92,239,65,72,225,10,64,108,42,92,239,65,73,225,10,64,108,94,226,237,65,2,150,254,
63,108,129,86,236,65,252,158,232,63,108,147,185,234,65,140,235,211,63,108,156,12,233,65,236,136,192,63,108,173,80,231,65,140,131,174,63,108,227,134,229,65,236,230,157,63,108,98,176,227,65,180,189,142,63,108,89,206,225,65,148,17,129,63,108,251,225,223,
65,144,214,105,63,108,42,92,223,65,8,215,99,63,108,42,92,223,65,12,215,99,63,108,42,92,223,65,16,215,99,63,108,107,36,218,65,176,63,42,63,108,80,215,212,65,0,38,242,62,108,62,120,207,65,32,225,160,62,108,165,10,202,65,64,201,65,62,108,254,145,196,65,
128,101,201,61,108,201,17,191,65,0,234,42,61,108,138,141,185,65,0,46,160,60,108,203,8,180,65,0,139,2,61,108,18,135,174,65,128,19,161,61,108,154,153,169,65,128,153,25,62,108,154,153,169,65,154,153,25,62,108,154,153,169,65,160,153,25,62,108,162,198,166,
65,224,114,72,62,108,65,249,163,65,16,167,132,62,108,66,51,161,65,0,1,174,62,108,105,118,158,65,192,44,224,62,108,120,196,155,65,32,133,13,63,108,41,31,153,65,224,57,47,63,108,44,136,150,65,24,31,85,63,108,43,1,148,65,136,28,127,63,108,195,139,145,65,
168,139,150,63,108,0,0,144,65,104,102,166,63,108,0,0,144,65,102,102,166,63,108,0,0,144,65,102,102,166,63,108,45,87,143,65,231,184,174,63,108,56,181,142,65,191,143,183,63,108,135,26,142,65,72,229,192,63,108,123,20,142,65,174,71,193,63,108,123,20,142,65,
174,71,193,63,108,62,10,141,65,215,163,208,63,108,52,51,137,65,133,235,1,64,108,225,122,142,65,0,0,0,64,108,224,122,142,65,0,0,0,64,108,24,10,149,65,192,9,247,63,108,97,158,155,65,32,85,243,63,108,134,51,162,65,144,228,244,63,108,80,197,168,65,16,183,
251,63,108,164,112,171,65,0,0,0,64,108,164,112,171,65,0,0,0,64,108,164,112,171,65,0,0,0,64,108,134,137,172,65,121,157,0,64,108,18,161,173,65,13,171,1,64,108,150,182,174,65,17,40,3,64,108,95,201,175,65,144,19,5,64,108,190,216,176,65,81,108,7,64,108,6,
228,177,65,211,48,10,64,108,139,234,178,65,79,95,13,64,108,165,235,179,65,191,245,16,64,108,177,230,180,65,212,241,20,64,108,12,219,181,65,4,81,25,64,108,28,200,182,65,129,16,30,64,108,71,173,183,65,66,45,35,64,108,252,137,184,65,2,164,40,64,108,174,
93,185,65,65,113,46,64,108,212,39,186,65,73,145,52,64,108,238,231,186,65,48,0,59,64,108,164,112,187,65,0,0,64,64,108,164,112,187,65,0,0,64,64,98,31,133,191,65,154,153,105,64,154,153,189,65,0,0,144,64,123,20,190,65,194,245,168,64,108,0,0,0,0,61,10,15,
65,108,61,10,71,64,92,143,252,65,108,72,225,128,65,92,143,236,65,108,72,225,128,65,92,143,236,65,108,67,216,128,65,164,79,237,65,108,222,216,128,65,33,16,238,65,108,72,225,128,65,82,184,238,65,108,72,225,128,65,82,184,238,65,108,72,225,128,65,81,184,
238,65,108,41,216,128,65,131,158,239,65,108,142,218,128,65,224,132,240,65,108,118,232,128,65,213,106,241,65,108,216,1,129,65,206,79,242,65,108,163,38,129,65,57,51,243,65,108,192,86,129,65,133,20,244,65,108,17,146,129,65,33,243,244,65,108,111,216,129,
65,127,206,245,65,108,172,41,130,65,18,166,246,65,108,151,133,130,65,81,121,247,65,108,242,235,130,65,180,71,248,65,108,126,92,131,65,184,16,249,65,108,241,214,131,65,219,211,249,65,108,254,90,132,65,162,144,250,65,108,80,232,132,65,146,70,251,65,108,
140,126,133,65,56,245,251,65,108,20,174,133,65,245,40,252,65,108,21,174,133,65,246,40,252,65,108,21,174,133,65,246,40,252,65,108,192,107,134,65,228,215,252,65,108,237,49,135,65,31,125,253,65,108,28,0,136,65,62,24,254,65,108,202,213,136,65,222,168,254,
65,108,110,178,137,65,161,46,255,65,108,123,149,138,65,50,169,255,65,108,96,126,139,65,33,12,0,66,108,135,108,140,65,198,61,0,66,108,88,95,141,65,104,105,0,66,108,56,86,142,65,234,142,0,66,108,137,80,143,65,52,174,0,66,108,171,77,144,65,52,199,0,66,108,
251,76,145,65,216,217,0,66,108,214,77,146,65,20,230,0,66,108,153,79,147,65,226,235,0,66,108,113,61,148,65,133,235,0,66,108,113,61,148,65,133,235,0,66,108,41,92,149,65,133,235,0,66,108,41,92,149,65,133,235,0,66,108,248,181,150,65,185,228,0,66,108,171,
14,152,65,75,213,0,66,108,100,101,153,65,69,189,0,66,108,73,185,154,65,181,156,0,66,108,128,9,156,65,178,115,0,66,108,50,85,157,65,86,66,0,66,108,138,155,158,65,190,8,0,66,108,185,219,159,65,36,142,255,65,108,240,20,161,65,245,250,254,65,108,105,70,162,
65,77,88,254,65,108,94,111,163,65,150,166,253,65,108,19,143,164,65,63,230,252,65,108,206,164,165,65,197,23,252,65,108,223,175,166,65,171,59,251,65,108,31,133,167,65,225,122,250,65,108,31,133,167,65,225,122,250,65,108,31,133,167,65,225,122,250,65,108,
198,77,168,65,122,12,249,65,108,222,3,169,65,129,148,247,65,108,240,166,169,65,230,19,246,65,108,150,54,170,65,160,139,244,65,108,114,178,170,65,169,252,242,65,108,195,245,170,65,0,0,242,65,108,195,245,170,65,0,0,242,65,108,0,0,174,65,154,153,229,65,
108,0,0,174,65,154,153,229,65,108,174,71,247,65,236,81,218,65,108,0,0,224,65,215,163,200,64,98,133,235,225,65,246,40,196,64,20,174,227,65,31,133,179,64,113,61,230,65,92,143,178,64,98,41,92,235,65,235,81,176,64,31,133,239,65,0,0,176,64,113,61,242,65,82,
184,190,64,108,113,61,242,65,81,184,190,64,108,167,157,242,65,199,232,192,64,108,191,4,243,65,77,5,195,64,108,119,114,243,65,138,12,197,64,108,136,230,243,65,49,253,198,64,108,170,96,244,65,5,214,200,64,108,140,224,244,65,216,149,202,64,108,222,101,245,
65,138,59,204,64,108,74,240,245,65,14,198,205,64,108,120,127,246,65,104,52,207,64,108,12,19,247,65,172,133,208,64,108,167,170,247,65,4,185,209,64,108,233,69,248,65,171,205,210,64,108,111,228,248,65,239,194,211,64,108,210,133,249,65,52,152,212,64,108,
171,41,250,65,241,76,213,64,108,146,207,250,65,179,224,213,64,108,29,119,251,65,26,83,214,64,108,154,153,251,65,102,102,214,64,108,154,153,251,65,102,102,214,64,108,154,153,251,65,101,102,214,64,108,75,161,252,65,236,19,215,64,108,125,166,253,65,242,
245,215,64,108,136,168,254,65,231,11,217,64,108,199,166,255,65,26,85,218,64,108,185,30,0,66,50,51,219,64,108,185,30,0,66,51,51,219,64,108,184,30,0,66,51,51,219,64,108,205,56,0,66,29,136,219,64,108,97,83,0,66,126,210,219,64,108,99,110,0,66,39,18,220,64,
108,195,137,0,66,239,70,220,64,108,110,165,0,66,180,112,220,64,108,83,193,0,66,92,143,220,64,108,96,221,0,66,211,162,220,64,108,132,249,0,66,12,171,220,64,108,171,21,1,66,3,168,220,64,108,197,49,1,66,184,153,220,64,108,191,77,1,66,54,128,220,64,108,135,
105,1,66,141,91,220,64,108,11,133,1,66,211,43,220,64,108,59,160,1,66,40,241,219,64,108,4,187,1,66,178,171,219,64,108,85,213,1,66,156,91,219,64,108,71,225,1,66,51,51,219,64,108,72,225,1,66,51,51,219,64,108,72,225,1,66,51,51,219,64,108,35,251,1,66,24,167,
218,64,108,22,20,2,66,211,16,218,64,108,17,44,2,66,197,112,217,64,108,3,67,2,66,84,199,216,64,108,224,88,2,66,236,20,216,64,108,152,109,2,66,255,89,215,64,108,30,129,2,66,5,151,214,64,108,103,147,2,66,124,204,213,64,108,101,164,2,66,227,250,212,64,108,
16,180,2,66,194,34,212,64,108,91,194,2,66,163,68,211,64,108,62,207,2,66,20,97,210,64,108,178,218,2,66,166,120,209,64,108,174,228,2,66,239,139,208,64,108,44,237,2,66,134,155,207,64,108,39,244,2,66,4,168,206,64,108,195,245,2,66,102,102,206,64,108,195,245,
2,66,102,102,206,64,98,134,235,3,66,10,215,179,64,72,225,4,66,153,153,153,64,72,225,5,66,122,20,126,64,98,184,30,7,66,0,0,64,64,133,235,6,66,143,194,53,64,72,225,2,66,41,92,31,64,99,109,0,0,64,65,133,235,157,65,108,215,163,60,65,133,235,157,65,108,72,
225,38,65,31,133,185,65,108,72,225,38,65,31,133,185,65,108,1,178,38,65,28,205,185,65,108,150,123,38,65,211,19,186,65,108,44,62,38,65,23,89,186,65,108,232,249,37,65,188,156,186,65,108,248,174,37,65,151,222,186,65,108,138,93,37,65,125,30,187,65,108,211,
5,37,65,70,92,187,65,108,11,168,36,65,202,151,187,65,108,110,68,36,65,227,208,187,65,108,60,219,35,65,108,7,188,65,108,184,108,35,65,67,59,188,65,108,41,249,34,65,71,108,188,65,108,217,128,34,65,87,154,188,65,108,103,102,34,65,216,163,188,65,108,103,
102,34,65,215,163,188,65,108,1,0,36,65,184,30,189,65,108,155,153,33,65,215,163,190,65,108,247,40,8,65,215,163,206,65,108,82,184,230,64,0,0,220,65,108,72,225,226,64,0,0,220,65,108,72,225,226,64,0,0,220,65,108,85,204,225,64,122,237,219,65,108,110,187,224,
64,132,215,219,65,108,67,175,223,64,44,190,219,65,108,126,168,222,64,131,161,219,65,108,144,194,221,64,31,133,219,65,108,144,194,221,64,31,133,219,65,108,134,235,217,64,62,10,219,65,108,134,235,217,64,52,51,217,65,98,32,133,219,64,206,204,212,65,165,
112,221,64,103,102,208,65,42,92,223,64,1,0,204,65,108,93,143,226,64,196,245,196,65,98,226,122,228,64,196,245,192,65,124,20,230,64,196,245,188,65,21,174,231,64,196,245,184,65,108,21,174,231,64,196,245,184,65,108,88,169,231,64,131,191,184,65,108,117,175,
231,64,68,137,184,65,108,105,192,231,64,42,83,184,65,108,40,220,231,64,88,29,184,65,108,160,2,232,64,240,231,183,65,108,186,51,232,64,19,179,183,65,108,85,111,232,64,229,126,183,65,108,76,181,232,64,134,75,183,65,108,113,5,233,64,24,25,183,65,108,146,
95,233,64,186,231,182,65,108,116,195,233,64,140,183,182,65,108,217,48,234,64,172,136,182,65,108,121,167,234,64,58,91,182,65,108,9,39,235,64,82,47,182,65,108,55,175,235,64,16,5,182,65,108,173,63,236,64,143,220,181,65,108,13,216,236,64,233,181,181,65,108,
247,119,237,64,55,145,181,65,108,123,20,238,64,165,112,181,65,108,123,20,238,64,165,112,181,65,108,123,20,238,64,165,112,181,65,108,123,20,238,64,165,112,181,65,108,123,20,238,64,165,112,181,65,108,45,199,237,64,89,66,181,65,108,57,131,237,64,36,19,181,
65,108,202,72,237,64,37,227,180,65,108,7,24,237,64,122,178,180,65,108,14,241,236,64,66,129,180,65,108,248,211,236,64,158,79,180,65,108,217,192,236,64,173,29,180,65,108,187,183,236,64,142,235,179,65,108,165,184,236,64,99,185,179,65,108,151,195,236,64,
74,135,179,65,108,137,216,236,64,101,85,179,65,108,110,247,236,64,210,35,179,65,108,50,32,237,64,178,242,178,65,108,188,82,237,64,36,194,178,65,108,234,142,237,64,71,146,178,65,108,150,212,237,64,59,99,178,65,108,123,20,238,64,115,61,178,65,108,123,20,
238,64,114,61,178,65,108,154,153,5,65,134,235,159,65,108,154,153,5,65,134,235,159,65,108,17,95,5,65,76,48,160,65,108,186,29,5,65,134,115,160,65,108,192,213,4,65,9,181,160,65,108,80,135,4,65,170,244,160,65,108,158,50,4,65,65,50,161,65,108,222,215,3,65,
166,109,161,65,108,76,119,3,65,180,166,161,65,108,36,17,3,65,69,221,161,65,108,169,165,2,65,56,17,162,65,108,31,53,2,65,107,66,162,65,108,206,191,1,65,190,112,162,65,108,1,70,1,65,19,156,162,65,108,6,200,0,65,80,196,162,65,108,46,70,0,65,89,233,162,65,
108,151,129,255,64,25,11,163,65,108,104,112,254,64,120,41,163,65,108,127,89,253,64,99,68,163,65,108,141,61,252,64,202,91,163,65,108,72,29,251,64,157,111,163,65,108,105,249,249,64,208,127,163,65,108,170,210,248,64,88,140,163,65,108,200,169,247,64,45,149,
163,65,108,84,184,246,64,154,153,163,65,108,83,184,246,64,154,153,163,65,98,73,225,218,64,103,102,164,65,93,143,194,64,174,71,165,65,32,133,171,64,246,40,166,65,108,20,174,167,64,246,40,166,65,108,20,174,167,64,246,40,166,65,108,175,237,166,64,123,42,
166,65,108,57,45,166,64,152,41,166,65,108,47,109,165,64,78,38,166,65,108,10,174,164,64,159,32,166,65,108,69,240,163,64,142,24,166,65,108,90,52,163,64,33,14,166,65,108,192,122,162,64,94,1,166,65,108,239,195,161,64,77,242,165,65,108,91,16,161,64,249,224,
165,65,108,120,96,160,64,107,205,165,65,108,182,180,159,64,178,183,165,65,108,131,13,159,64,217,159,165,65,108,73,107,158,64,242,133,165,65,108,102,102,158,64,31,133,165,65,108,102,102,158,64,31,133,165,65,108,102,102,158,64,31,133,165,65,108,235,187,
157,64,65,93,165,65,108,159,25,157,64,77,51,165,65,108,234,127,156,64,96,7,165,65,108,46,239,155,64,150,217,164,65,108,200,103,155,64,11,170,164,65,108,14,234,154,64,222,120,164,65,108,82,118,154,64,46,70,164,65,108,220,12,154,64,29,18,164,65,108,241,
173,153,64,203,220,163,65,108,205,89,153,64,91,166,163,65,108,166,16,153,64,238,110,163,65,108,171,210,152,64,170,54,163,65,108,3,160,152,64,177,253,162,65,108,208,120,152,64,41,196,162,65,108,42,93,152,64,53,138,162,65,108,236,81,152,64,103,102,162,
65,108,235,81,152,64,103,102,162,65,98,81,184,150,64,226,122,158,65,245,40,148,64,103,102,154,65,153,153,145,64,93,143,150,65,108,123,20,142,64,0,0,144,65,108,113,61,170,64,72,225,142,65,108,52,51,19,65,11,215,137,65,108,236,81,24,65,165,112,137,65,108,
123,20,22,65,196,245,140,65,108,174,71,49,65,44,92,87,65,108,174,71,49,65,44,92,87,65,108,71,107,49,65,253,249,86,65,108,189,147,49,65,182,153,86,65,108,246,192,49,65,146,59,86,65,108,214,242,49,65,208,223,85,65,108,59,41,50,65,168,134,85,65,108,3,100,
50,65,86,48,85,65,108,10,163,50,65,15,221,84,65,108,37,230,50,65,9,141,84,65,108,43,45,51,65,119,64,84,65,108,238,119,51,65,139,247,83,65,108,62,198,51,65,114,178,83,65,108,233,23,52,65,90,113,83,65,108,187,108,52,65,107,52,83,65,108,125,196,52,65,205,
251,82,65,108,248,30,53,65,164,199,82,65,108,240,123,53,65,17,152,82,65,108,44,219,53,65,51,109,82,65,108,133,235,53,65,105,102,82,65,108,133,235,53,65,105,102,82,65,108,133,235,53,65,105,102,82,65,108,133,235,53,65,105,102,82,65,108,247,194,53,65,243,
3,82,65,108,97,159,53,65,150,159,81,65,108,220,128,53,65,146,57,81,65,108,121,103,53,65,39,210,80,65,108,73,83,53,65,153,105,80,65,108,90,68,53,65,43,0,80,65,108,180,58,53,65,30,150,79,65,108,95,54,53,65,185,43,79,65,108,92,55,53,65,62,193,78,65,108,
171,61,53,65,241,86,78,65,108,72,73,53,65,24,237,77,65,108,44,90,53,65,245,131,77,65,108,76,112,53,65,203,27,77,65,108,153,139,53,65,222,180,76,65,108,2,172,53,65,111,79,76,65,108,115,209,53,65,192,235,75,65,108,133,235,53,65,23,174,75,65,108,133,235,
53,65,23,174,75,65,98,10,215,55,65,33,133,71,65,153,153,57,65,54,51,67,65,41,92,59,65,64,10,63,65,108,195,245,60,65,54,51,59,65,108,195,245,60,65,54,51,59,65,108,231,104,61,65,49,40,58,65,108,63,233,61,65,67,35,57,65,108,120,118,62,65,19,37,56,65,108,
57,16,63,65,66,46,55,65,108,30,182,63,65,112,63,54,65,108,189,103,64,65,53,89,53,65,108,166,36,65,65,36,124,52,65,108,94,236,65,65,203,168,51,65,108,103,190,66,65,177,223,50,65,108,58,154,67,65,87,33,50,65,108,73,127,68,65,54,110,49,65,108,4,109,69,65,
193,198,48,65,108,209,98,70,65,99,43,48,65,108,19,96,71,65,128,156,47,65,108,40,100,72,65,115,26,47,65,108,106,110,73,65,144,165,46,65,108,46,126,74,65,32,62,46,65,108,199,146,75,65,102,228,45,65,108,131,171,76,65,157,152,45,65,108,176,199,77,65,243,
90,45,65,108,150,230,78,65,146,43,45,65,108,127,7,80,65,150,10,45,65,108,177,41,81,65,21,248,44,65,108,164,112,81,65,197,245,44,65,108,164,112,81,65,197,245,44,65,108,113,61,82,65,197,245,44,65,108,113,61,82,65,197,245,44,65,108,41,92,87,65,64,10,47,
65,108,41,92,87,65,64,10,47,65,108,39,152,90,65,130,71,48,65,108,65,195,93,65,192,173,49,65,108,111,219,96,65,22,60,51,65,108,41,92,99,65,218,163,52,65,108,41,92,99,65,218,163,52,65,108,41,92,99,65,218,163,52,65,108,9,21,100,65,154,21,53,65,108,254,199,
100,65,115,144,53,65,108,150,116,101,65,22,20,54,65,108,99,26,102,65,48,160,54,65,108,250,184,102,65,102,52,55,65,108,247,79,103,65,89,208,55,65,108,247,222,103,65,167,115,56,65,108,160,101,104,65,230,29,57,65,108,156,227,104,65,169,206,57,65,108,154,
88,105,65,128,133,58,65,108,80,196,105,65,245,65,59,65,108,119,38,106,65,144,3,60,65,108,210,126,106,65,213,201,60,65,108,40,205,106,65,69,148,61,65,108,71,17,107,65,94,98,62,65,108,3,75,107,65,157,51,63,65,108,55,122,107,65,124,7,64,65,108,198,158,107,
65,115,221,64,65,108,151,184,107,65,249,180,65,65,108,154,199,107,65,133,141,66,65,108,198,203,107,65,140,102,67,65,108,24,197,107,65,130,63,68,65,108,148,179,107,65,221,23,69,65,108,69,151,107,65,20,239,69,65,108,62,112,107,65,155,196,70,65,108,151,
62,107,65,234,151,71,65,108,113,2,107,65,123,104,72,65,108,241,187,106,65,199,53,73,65,108,69,107,106,65,75,255,73,65,108,160,16,106,65,135,196,74,65,108,143,194,105,65,44,92,75,65,108,143,194,105,65,44,92,75,65,108,51,51,103,65,167,112,81,65,98,153,
153,101,65,187,30,85,65,0,0,100,65,208,204,88,65,92,143,98,65,218,163,92,65,108,92,143,98,65,218,163,92,65,108,194,90,98,65,159,16,93,65,108,202,32,98,65,160,122,93,65,108,152,225,97,65,153,225,93,65,108,84,157,97,65,73,69,94,65,108,43,84,97,65,111,165,
94,65,108,75,6,97,65,207,1,95,65,108,230,179,96,65,44,90,95,65,108,49,93,96,65,80,174,95,65,108,99,2,96,65,2,254,95,65,108,0,0,96,65,0,0,96,65,108,0,0,96,65,0,0,96,65,108,164,112,97,65,195,245,96,65,108,225,122,96,65,41,92,99,65,108,41,92,95,65,113,61,
102,65,108,41,92,95,65,246,40,104,65,108,143,194,81,65,184,30,133,65,108,215,163,84,65,184,30,133,65,108,41,92,137,65,0,0,128,65,108,41,92,137,65,0,0,128,65,108,223,193,137,65,204,11,128,65,108,10,40,138,65,126,18,128,65,108,107,142,138,65,20,20,128,
65,108,191,244,138,65,139,16,128,65,108,197,90,139,65,229,7,128,65,108,155,153,139,65,0,0,128,65,108,154,153,139,65,0,0,128,65,108,154,153,139,65,0,0,128,65,108,0,5,140,65,146,154,127,65,108,205,114,140,65,1,64,127,65,108,186,226,140,65,134,240,126,65,
108,128,84,141,65,86,172,126,65,108,213,199,141,65,154,115,126,65,108,113,60,142,65,120,70,126,65,108,8,178,142,65,12,37,126,65,108,79,40,143,65,107,15,126,65,108,251,158,143,65,165,5,126,65,108,192,21,144,65,190,7,126,65,108,81,140,144,65,182,21,126,
65,108,98,2,145,65,131,47,126,65,108,169,119,145,65,22,85,126,65,108,218,235,145,65,85,134,126,65,108,171,94,146,65,34,195,126,65,108,210,207,146,65,85,11,127,65,108,6,63,147,65,193,94,127,65,108,2,172,147,65,48,189,127,65,108,127,22,148,65,51,19,128,
65,108,56,126,148,65,15,77,128,65,108,236,226,148,65,8,140,128,65,108,90,68,149,65,245,207,128,65,108,68,162,149,65,171,24,129,65,108,110,252,149,65,252,101,129,65,108,157,82,150,65,181,183,129,65,108,155,164,150,65,163,13,130,65,108,52,242,150,65,143,
103,130,65,108,53,59,151,65,62,197,130,65,108,112,127,151,65,118,38,131,65,108,186,190,151,65,247,138,131,65,108,233,248,151,65,130,242,131,65,108,0,0,152,65,0,0,132,65,108,0,0,152,65,0,0,132,65,98,133,235,153,65,205,204,134,65,113,61,156,65,154,153,
137,65,215,163,158,65,92,143,140,65,108,123,20,162,65,205,204,144,65,108,143,194,163,65,195,245,146,65,108,61,10,161,65,164,112,147,65,99,109,174,71,209,65,246,40,186,65,108,174,71,209,65,246,40,186,65,108,217,203,204,65,48,238,183,65,108,249,109,200,
65,196,122,181,65,108,220,48,196,65,64,208,178,65,108,53,23,192,65,92,240,175,65,108,247,40,188,65,72,225,172,65,108,246,40,188,65,72,225,172,65,98,51,51,185,65,82,184,168,65,164,112,189,65,103,102,156,65,10,215,189,65,195,245,158,65,108,10,215,189,65,
195,245,158,65,108,170,153,190,65,102,134,158,65,108,122,86,191,65,114,13,158,65,108,2,13,192,65,53,139,157,65,108,206,188,192,65,2,0,157,65,108,71,225,192,65,72,225,156,65,108,71,225,192,65,72,225,156,65,98,204,204,194,65,195,245,154,65,225,122,196,
65,41,92,155,65,214,163,198,65,72,225,156,65,108,214,163,198,65,72,225,156,65,108,92,203,199,65,106,214,157,65,108,68,230,200,65,3,218,158,65,108,215,243,201,65,109,235,159,65,108,105,243,202,65,249,9,161,65,108,88,228,203,65,238,52,162,65,108,8,198,
204,65,143,107,163,65,108,234,151,205,65,20,173,164,65,108,119,89,206,65,175,248,165,65,108,51,10,207,65,141,77,167,65,108,174,169,207,65,211,170,168,65,108,128,55,208,65,162,15,170,65,108,80,179,208,65,21,123,171,65,108,206,28,209,65,68,236,172,65,108,
183,115,209,65,66,98,174,65,108,211,183,209,65,33,220,175,65,108,246,232,209,65,238,88,177,65,108,2,7,210,65,183,215,178,65,108,226,17,210,65,133,87,180,65,108,144,9,210,65,100,215,181,65,108,18,238,209,65,93,86,183,65,108,120,191,209,65,124,211,184,
65,108,31,133,209,65,246,40,186,65,108,31,133,209,65,246,40,186,65,99,109,102,102,4,66,61,10,119,64,98,102,102,3,66,143,194,149,64,163,112,2,66,0,0,176,64,225,122,1,66,92,143,202,64,98,225,122,1,66,61,10,207,64,51,51,1,66,41,92,207,64,51,51,1,66,41,92,
207,64,98,51,51,1,66,41,92,207,64,51,51,1,66,41,92,207,64,82,184,0,66,41,92,207,64,108,82,184,0,66,42,92,207,64,108,148,39,0,66,86,193,205,64,108,229,40,255,65,230,96,204,64,108,153,254,253,65,186,59,203,64,108,3,209,252,65,142,82,202,64,108,246,40,252,
65,134,235,201,64,108,246,40,252,65,133,235,201,64,108,246,40,252,65,133,235,201,64,108,163,168,251,65,118,151,201,64,108,134,41,251,65,218,41,201,64,108,240,171,250,65,248,162,200,64,108,49,48,250,65,38,3,200,64,108,154,182,249,65,202,74,199,64,108,
119,63,249,65,89,122,198,64,108,20,203,248,65,90,146,197,64,108,190,89,248,65,98,147,196,64,108,187,235,247,65,18,126,195,64,108,82,129,247,65,28,83,194,64,108,200,26,247,65,65,19,193,64,108,93,184,246,65,75,191,191,64,108,81,90,246,65,22,88,190,64,108,
225,0,246,65,135,222,188,64,108,69,172,245,65,142,83,187,64,108,179,92,245,65,42,184,185,64,108,94,18,245,65,97,13,184,64,108,195,245,244,65,42,92,183,64,108,195,245,244,65,41,92,183,64,108,195,245,244,65,41,92,183,64,108,43,115,244,65,87,55,181,64,108,
225,233,243,65,80,45,179,64,108,62,90,243,65,99,63,177,64,108,156,196,242,65,203,110,175,64,108,92,41,242,65,177,188,173,64,108,225,136,241,65,44,42,172,64,108,146,227,240,65,60,184,170,64,108,217,57,240,65,208,103,169,64,108,34,140,239,65,189,57,168,
64,108,220,218,238,65,197,46,167,64,108,121,38,238,65,148,71,166,64,108,108,111,237,65,188,132,165,64,108,43,182,236,65,187,230,164,64,108,43,251,235,65,245,109,164,64,108,229,62,235,65,185,26,164,64,108,209,129,234,65,58,237,163,64,108,104,196,233,65,
152,229,163,64,108,35,7,233,65,213,3,164,64,108,123,74,232,65,223,71,164,64,108,234,142,231,65,139,177,164,64,108,230,212,230,65,148,64,165,64,108,231,28,230,65,160,244,165,64,108,0,0,230,65,123,20,166,64,108,0,0,230,65,123,20,166,64,98,164,112,227,65,
123,20,166,64,123,20,226,65,123,20,182,64,123,20,224,65,113,61,186,64,108,21,174,223,65,113,61,186,64,108,21,174,223,65,113,61,186,64,108,191,249,222,65,78,25,188,64,108,148,75,222,65,159,24,190,64,108,5,164,221,65,30,58,192,64,108,125,3,221,65,111,124,
194,64,108,97,106,220,65,30,222,196,64,108,21,217,219,65,166,93,199,64,108,245,79,219,65,110,249,201,64,108,89,207,218,65,202,175,204,64,108,147,87,218,65,254,126,207,64,108,240,232,217,65,61,101,210,64,108,182,131,217,65,173,96,213,64,108,39,40,217,
65,102,111,216,64,108,125,214,216,65,113,143,219,64,108,216,163,216,65,144,194,221,64,108,216,163,216,65,144,194,221,64,108,216,163,216,65,140,194,221,64,108,162,174,208,65,46,8,28,65,108,210,220,201,65,72,236,73,65,108,50,51,201,65,76,225,78,65,108,
52,51,201,65,72,225,78,65,98,83,184,200,65,144,194,81,65,113,61,200,65,226,122,84,65,144,194,199,65,11,215,87,65,108,164,112,197,65,134,235,105,65,108,92,143,196,65,1,0,112,65,98,10,215,197,65,124,20,106,65,61,10,217,65,62,10,99,65,92,143,220,65,1,0,
100,65,98,102,102,222,65,1,0,100,65,205,204,222,65,83,184,102,65,72,225,222,65,11,215,103,65,98,31,133,223,65,93,143,114,65,52,51,225,65,134,235,131,65,52,51,225,65,236,81,132,65,108,52,51,225,65,144,194,133,65,108,144,194,223,65,144,194,133,65,98,246,
40,206,65,246,40,138,65,226,122,198,65,124,20,140,65,62,10,195,65,216,163,140,65,108,102,102,194,65,216,163,140,65,108,102,102,194,65,216,163,140,65,98,92,143,192,65,216,163,140,65,225,122,192,65,216,163,140,65,235,81,192,65,11,215,139,65,108,235,81,
192,65,175,71,139,65,108,40,92,189,65,144,194,151,65,108,40,92,187,65,144,194,159,65,113,40,92,179,65,236,81,194,65,81,184,170,65,72,225,228,65,108,0,0,168,65,174,71,241,65,108,0,0,168,65,174,71,241,65,108,154,165,167,65,119,181,242,65,108,8,57,167,65,
71,30,244,65,108,145,186,166,65,55,129,245,65,108,133,42,166,65,98,221,246,65,108,64,137,165,65,236,49,248,65,108,195,245,164,65,174,71,249,65,108,195,245,164,65,174,71,249,65,108,195,245,164,65,174,71,249,65,108,195,13,164,65,225,5,250,65,108,140,28,
163,65,63,184,250,65,108,183,34,162,65,86,94,251,65,108,229,32,161,65,186,247,251,65,108,188,23,160,65,11,132,252,65,108,227,7,159,65,239,2,253,65,108,11,242,157,65,20,116,253,65,108,227,214,156,65,49,215,253,65,108,34,183,155,65,8,44,254,65,108,128,
147,154,65,98,114,254,65,108,182,108,153,65,19,170,254,65,108,131,67,152,65,246,210,254,65,108,163,24,151,65,241,236,254,65,108,215,236,149,65,244,247,254,65,108,195,245,148,65,194,245,254,65,108,195,245,148,65,194,245,254,65,108,195,245,148,65,194,245,
254,65,108,194,245,148,65,194,245,254,65,108,226,31,148,65,208,252,254,65,108,235,73,147,65,43,249,254,65,108,104,116,146,65,214,234,254,65,108,225,159,145,65,217,209,254,65,108,221,204,144,65,70,174,254,65,108,227,251,143,65,49,128,254,65,108,123,45,
143,65,186,71,254,65,108,38,98,142,65,4,5,254,65,108,105,154,141,65,57,184,253,65,108,193,214,140,65,140,97,253,65,108,174,23,140,65,51,1,253,65,108,168,93,139,65,108,151,252,65,108,39,169,138,65,123,36,252,65,108,158,250,137,65,169,168,251,65,108,126,
82,137,65,70,36,251,65,108,49,177,136,65,166,151,250,65,108,31,23,136,65,35,3,250,65,108,0,0,136,65,133,235,249,65,108,0,0,136,65,133,235,249,65,108,0,0,136,65,133,235,249,65,108,62,130,135,65,129,92,249,65,108,201,11,135,65,97,199,248,65,108,238,156,
134,65,134,44,248,65,108,245,53,134,65,82,140,247,65,108,30,215,133,65,43,231,246,65,108,166,128,133,65,124,61,246,65,108,197,50,133,65,177,143,245,65,108,172,237,132,65,57,222,244,65,108,137,177,132,65,134,41,244,65,108,128,126,132,65,11,114,243,65,
108,180,84,132,65,62,184,242,65,108,62,52,132,65,149,252,241,65,108,52,29,132,65,137,63,241,65,108,164,15,132,65,147,129,240,65,108,150,11,132,65,45,195,239,65,108,14,17,132,65,207,4,239,65,108,123,20,132,65,205,204,238,65,108,123,20,132,65,205,204,238,
65,108,123,20,132,65,205,204,238,65,108,249,34,132,65,110,34,238,65,108,247,57,132,65,254,120,237,65,108,101,89,132,65,234,208,236,65,108,47,129,132,65,158,42,236,65,108,60,177,132,65,133,134,235,65,108,82,184,132,65,164,112,235,65,108,82,184,132,65,
164,112,235,65,108,82,184,132,65,164,112,235,65,98,82,184,132,65,215,163,234,65,184,30,133,65,10,215,233,65,31,133,133,65,195,245,232,65,113,62,10,149,65,195,245,188,65,215,163,164,65,195,245,144,65,98,113,61,162,65,246,40,142,65,133,235,159,65,164,112,
139,65,154,153,157,65,195,245,136,65,108,215,163,88,65,41,92,27,65,108,215,163,88,65,41,92,27,65,108,18,241,87,65,185,170,26,65,108,101,71,87,65,146,240,25,65,108,59,167,86,65,44,46,25,65,108,252,16,86,65,3,100,24,65,108,8,133,85,65,152,146,23,65,108,
183,3,85,65,114,186,22,65,108,94,141,84,65,26,220,21,65,108,72,34,84,65,31,248,20,65,108,184,194,83,65,19,15,20,65,108,237,110,83,65,139,33,19,65,108,28,39,83,65,30,48,18,65,108,115,235,82,65,104,59,17,65,108,24,188,82,65,5,68,16,65,108,41,153,82,65,
147,74,15,65,108,189,130,82,65,178,79,14,65,108,226,120,82,65,3,84,13,65,108,159,123,82,65,38,88,12,65,108,241,138,82,65,188,92,11,65,108,207,166,82,65,103,98,10,65,108,39,207,82,65,199,105,9,65,108,224,3,83,65,122,115,8,65,108,214,68,83,65,31,128,7,
65,108,226,145,83,65,80,144,6,65,108,209,234,83,65,168,164,5,65,108,107,79,84,65,190,189,4,65,108,112,191,84,65,36,220,3,65,108,150,58,85,65,108,0,3,65,108,145,192,85,65,34,43,2,65,108,10,81,86,65,207,92,1,65,108,165,235,86,65,245,149,0,65,108,254,143,
87,65,44,174,255,64,108,173,61,88,65,85,65,254,64,108,66,244,88,65,79,230,252,64,108,73,179,89,65,248,157,251,64,108,143,194,89,65,30,133,251,64,108,143,194,89,65,31,133,251,64,108,143,194,89,65,31,133,251,64,108,228,141,90,65,231,32,250,64,108,222,97,
91,65,116,209,248,64,108,247,61,92,65,158,151,247,64,108,161,33,93,65,44,116,246,64,108,75,12,94,65,216,103,245,64,108,94,253,94,65,80,115,244,64,108,65,244,95,65,46,151,243,64,108,84,240,96,65,1,212,242,64,108,248,240,97,65,68,42,242,64,108,136,245,
98,65,102,154,241,64,108,92,253,99,65,192,36,241,64,108,205,7,101,65,160,201,240,64,108,47,20,102,65,62,137,240,64,108,215,33,103,65,198,99,240,64,108,25,48,104,65,77,89,240,64,108,72,62,105,65,220,105,240,64,108,182,75,106,65,102,149,240,64,108,183,
87,107,65,210,219,240,64,108,160,97,108,65,241,60,241,64,108,198,104,109,65,134,184,241,64,108,130,108,110,65,65,78,242,64,108,45,108,111,65,194,253,242,64,108,35,103,112,65,154,198,243,64,108,197,92,113,65,71,168,244,64,108,115,76,114,65,57,162,245,
64,108,151,53,115,65,209,179,246,64,108,153,23,116,65,96,220,247,64,108,234,241,116,65,38,27,249,64,108,253,195,117,65,90,111,250,64,108,78,141,118,65,32,216,251,64,108,89,77,119,65,146,84,253,64,108,166,3,120,65,189,227,254,64,108,225,122,120,65,0,0,
0,65,108,225,122,120,65,0,0,0,65,98,72,225,134,65,205,204,24,65,41,92,145,65,143,194,49,65,112,61,156,65,72,225,74,65,108,50,51,173,65,41,92,115,65,108,19,174,173,65,225,122,116,65,98,244,40,174,65,153,153,117,65,70,225,174,65,92,143,106,65,193,245,176,
65,123,20,94,65,108,193,245,176,65,195,245,92,65,108,0,0,184,65,184,30,53,65,98,10,215,185,65,10,215,39,65,143,194,187,65,92,143,26,65,20,174,189,65,164,112,13,65,108,20,174,189,65,164,112,13,65,108,54,195,190,65,198,99,6,65,108,228,170,191,65,233,122,
254,64,108,140,100,192,65,138,4,240,64,108,182,239,192,65,174,109,225,64,108,8,76,193,65,170,191,210,64,108,73,121,193,65,228,3,196,64,108,90,119,193,65,200,67,181,64,108,40,92,193,65,31,133,171,64,108,40,92,193,65,31,133,171,64,108,40,92,193,65,41,92,
167,64,108,40,92,193,65,41,92,167,64,98,71,225,192,65,164,112,141,64,214,163,194,65,41,92,95,64,122,20,190,65,215,163,48,64,108,122,20,190,65,215,163,48,64,108,65,68,189,65,169,17,41,64,108,48,104,188,65,39,213,33,64,108,210,128,187,65,244,242,26,64,
108,188,142,186,65,119,111,20,64,108,137,146,185,65,218,78,14,64,108,217,140,184,65,10,149,8,64,108,85,126,183,65,175,69,3,64,108,170,103,182,65,100,200,252,63,108,137,73,181,65,94,231,243,63,108,170,36,180,65,2,238,235,63,108,200,249,178,65,98,225,228,
63,108,163,201,177,65,8,198,222,63,108,253,148,176,65,216,159,217,63,108,156,92,175,65,30,114,213,63,108,71,33,174,65,136,63,210,63,108,201,227,172,65,32,10,208,63,108,235,81,172,65,42,92,207,63,108,235,81,172,65,41,92,207,63,108,235,81,172,65,40,92,
207,63,108,222,165,166,65,8,207,197,63,108,254,243,160,65,32,206,192,63,108,51,51,157,65,8,0,192,63,108,51,51,157,65,0,0,192,63,98,246,40,154,65,0,0,192,63,61,10,151,65,0,0,192,63,20,174,147,65,0,0,192,63,108,20,174,147,65,0,0,192,63,108,171,15,150,65,
240,141,169,63,108,113,130,152,65,136,10,149,63,108,215,4,155,65,232,130,130,63,108,64,149,157,65,208,5,100,63,108,9,50,160,65,48,42,71,63,108,134,217,162,65,104,133,46,63,108,3,138,165,65,64,39,26,63,108,202,65,168,65,192,28,10,63,108,92,143,170,65,
0,0,0,63,108,92,143,170,65,0,0,0,63,108,92,143,170,65,0,0,0,63,108,108,226,175,65,64,224,216,62,108,154,59,181,65,0,213,194,62,108,122,151,186,65,64,236,189,62,108,159,242,191,65,96,41,202,62,108,155,73,197,65,96,132,231,62,108,3,153,202,65,64,245,10,
63,108,113,221,207,65,16,159,42,63,108,135,19,213,65,64,171,82,63,108,239,55,218,65,48,128,129,63,108,205,204,222,65,72,225,154,63,108,205,204,222,65,72,225,154,63,108,205,204,222,65,72,225,154,63,108,20,150,224,65,88,200,165,63,108,17,86,226,65,152,
25,178,63,108,165,11,228,65,40,205,191,63,108,185,181,229,65,60,218,206,63,108,58,83,231,65,54,55,223,63,108,34,227,232,65,162,217,240,63,108,112,100,234,65,25,219,1,64,108,45,214,235,65,108,224,11,64,108,109,55,237,65,95,118,22,64,108,154,153,237,65,
155,153,25,64,108,154,153,237,65,154,153,25,64,108,154,153,237,65,153,153,25,64,108,160,15,238,65,234,141,29,64,108,212,139,238,65,196,81,33,64,108,230,13,239,65,195,226,36,64,108,130,149,239,65,155,62,40,64,108,82,34,240,65,40,99,43,64,108,251,179,240,
65,102,78,46,64,108,33,74,241,65,120,254,48,64,108,100,228,241,65,164,113,51,64,108,96,130,242,65,92,166,53,64,108,177,35,243,65,50,155,55,64,108,239,199,243,65,233,78,57,64,108,177,110,244,65,105,192,58,64,108,141,23,245,65,198,238,59,64,108,23,194,
245,65,62,217,60,64,108,225,109,246,65,59,127,61,64,108,126,26,247,65,84,224,61,64,108,126,199,247,65,72,252,61,64,108,116,116,248,65,8,211,61,64,108,241,32,249,65,174,100,61,64,108,134,204,249,65,127,177,60,64,108,198,118,250,65,240,185,59,64,108,67,
31,251,65,156,126,58,64,108,146,197,251,65,80,0,57,64,108,72,105,252,65,0,64,55,64,108,253,9,253,65,202,62,53,64,108,154,153,253,65,52,51,51,64,108,154,153,253,65,52,51,51,64,108,154,153,253,65,52,51,51,64,108,37,16,254,65,60,177,49,64,108,244,136,254,
65,36,95,48,64,108,185,3,255,65,198,61,47,64,108,38,128,255,65,220,77,46,64,108,234,253,255,65,254,143,45,64,108,91,62,0,66,166,4,45,64,108,28,126,0,66,44,172,44,64,108,15,190,0,66,203,134,44,64,108,12,254,0,66,153,148,44,64,108,233,61,1,66,142,213,44,
64,108,126,125,1,66,128,73,45,64,108,162,188,1,66,37,240,45,64,108,45,251,1,66,18,201,46,64,108,245,56,2,66,189,211,47,64,108,213,117,2,66,123,15,49,64,108,165,177,2,66,130,123,50,64,108,205,204,2,66,52,51,51,64,108,205,204,2,66,52,51,51,64,98,174,71,
5,66,20,174,71,64,174,71,5,66,20,174,71,64,102,102,4,66,61,10,119,64,99,101,0,0 };
const uint8 visualStudio[] = { 110,109,0,0,112,65,0,0,0,0,108,0,0,227,64,0,0,253,64,108,0,0,0,64,0,0,128,64,108,0,0,0,0,0,0,160,64,108,0,0,0,0,0,0,112,65,108,0,0,0,64,0,0,128,65,108,0,0,224,64,0,0,64,65,108,0,0,112,65,0,0,160,65,108,0,0,160,65,0,0,144,65,108,0,0,160,65,0,0,0,64,108,
0,0,112,65,0,0,0,0,99,109,0,0,112,65,0,0,192,64,108,0,0,112,65,0,0,96,65,108,0,176,26,65,0,0,32,65,108,0,0,112,65,0,0,192,64,99,109,0,0,0,64,0,0,224,64,108,0,0,162,64,0,0,31,65,108,0,0,0,64,0,0,80,65,108,0,0,0,64,0,0,224,64,99,101,0,0 };
const uint8 clion[] = { 110,109,0,0,0,0,0,0,0,0,98,0,0,0,0,170,170,38,67,0,0,0,0,171,170,166,67,0,0,0,0,0,0,250,67,98,170,170,38,67,0,0,250,67,171,170,166,67,0,0,250,67,0,0,250,67,0,0,250,67,98,0,0,250,67,171,170,166,67,0,0,250,67,170,170,38,67,0,0,250,67,0,0,0,0,98,171,170,
166,67,0,0,0,0,170,170,38,67,0,0,0,0,0,0,0,0,0,0,0,0,99,109,246,164,21,67,176,231,121,66,98,120,35,52,67,168,63,118,66,22,248,83,67,248,250,142,66,0,128,104,67,0,0,190,66,98,172,234,94,67,0,128,212,66,86,85,85,67,0,0,235,66,2,192,75,67,0,192,0,67,98,
180,250,52,67,80,226,207,66,62,108,10,67,92,105,190,66,32,159,224,66,108,117,239,66,98,40,200,154,66,148,71,22,67,110,149,174,66,254,37,89,67,80,183,4,67,52,0,104,67,98,100,211,30,67,88,243,112,67,134,23,59,67,212,126,101,67,252,63,78,67,0,64,83,67,98,
84,213,87,67,86,213,92,67,170,106,97,67,174,106,102,67,0,0,107,67,2,0,112,67,98,28,218,67,67,144,199,143,67,12,199,231,66,24,70,145,67,174,142,147,66,200,71,117,67,98,16,130,199,65,74,191,69,67,80,114,21,66,130,44,211,66,170,64,198,66,178,0,150,66,98,
176,33,229,66,124,94,133,66,160,27,4,67,84,87,121,66,246,164,21,67,176,231,121,66,99,109,0,32,133,67,2,0,130,66,98,85,213,140,67,2,0,130,66,171,138,148,67,2,0,130,66,0,64,156,67,2,0,130,66,98,0,64,156,67,0,128,242,66,0,64,156,67,0,128,49,67,0,64,156,
67,4,192,105,67,98,1,64,171,67,4,192,105,67,0,64,186,67,4,192,105,67,0,64,201,67,4,192,105,67,98,0,64,201,67,174,170,118,67,0,64,201,67,171,202,129,67,0,64,201,67,1,64,136,67,98,170,138,178,67,1,64,136,67,86,213,155,67,1,64,136,67,0,32,133,67,1,64,136,
67,98,0,32,133,67,88,85,75,67,0,32,133,67,174,42,6,67,0,32,133,67,4,0,130,66,99,109,0,0,62,66,254,31,203,67,98,0,0,220,66,254,31,203,67,0,128,44,67,254,31,203,67,0,0,107,67,254,31,203,67,98,0,0,107,67,84,85,208,67,0,0,107,67,170,138,213,67,0,0,107,67,
0,192,218,67,98,0,128,44,67,0,192,218,67,0,0,220,66,0,192,218,67,252,255,61,66,0,192,218,67,98,252,255,61,66,170,138,213,67,252,255,61,66,84,85,208,67,252,255,61,66,254,31,203,67,99,101,0,0 };
}
Icons::Icons()
{
#define JUCE_LOAD_PATH_DATA(name) \
name.loadPathFromData (IconPathData::name, sizeof (IconPathData::name));
/* Some of the icon images used here are based on icons from this project:
http://raphaeljs.com/icons
They're MIT licensed - the licensing info is on the linked page.
*/
JUCE_LOAD_PATH_DATA (imageDoc)
JUCE_LOAD_PATH_DATA (config)
JUCE_LOAD_PATH_DATA (graph)
JUCE_LOAD_PATH_DATA (info)
JUCE_LOAD_PATH_DATA (warning)
JUCE_LOAD_PATH_DATA (user)
JUCE_LOAD_PATH_DATA (closedFolder)
JUCE_LOAD_PATH_DATA (exporter)
JUCE_LOAD_PATH_DATA (fileExplorer)
JUCE_LOAD_PATH_DATA (file)
JUCE_LOAD_PATH_DATA (modules)
JUCE_LOAD_PATH_DATA (openFolder)
JUCE_LOAD_PATH_DATA (settings)
JUCE_LOAD_PATH_DATA (singleModule)
JUCE_LOAD_PATH_DATA (plus);
JUCE_LOAD_PATH_DATA (android);
JUCE_LOAD_PATH_DATA (codeBlocks);
JUCE_LOAD_PATH_DATA (linux);
JUCE_LOAD_PATH_DATA (xcode);
JUCE_LOAD_PATH_DATA (visualStudio);
JUCE_LOAD_PATH_DATA (clion);
}

View File

@ -0,0 +1,86 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
struct Icon
{
Icon() = default;
Icon (const Path& pathToUse, Colour pathColour)
: path (pathToUse),
colour (pathColour)
{
}
void draw (Graphics& g, const juce::Rectangle<float>& area, bool isCrossedOut) const
{
if (! path.isEmpty())
{
g.setColour (colour);
const RectanglePlacement placement (RectanglePlacement::centred | RectanglePlacement::onlyReduceInSize);
g.fillPath (path, placement.getTransformToFit (path.getBounds(), area));
if (isCrossedOut)
{
g.setColour (Colours::red.withAlpha (0.8f));
g.drawLine ((float) area.getX(), area.getY() + area.getHeight() * 0.2f,
(float) area.getRight(), area.getY() + area.getHeight() * 0.8f, 3.0f);
}
}
}
Icon withContrastingColourTo (Colour background) const
{
return Icon (path, background.contrasting (colour, 0.6f));
}
Icon withColour (Colour newColour)
{
return Icon (path, newColour);
}
Path path;
Colour colour;
};
//==============================================================================
class Icons
{
public:
Icons();
Path imageDoc, config, graph, info, warning, user, closedFolder, exporter, fileExplorer, file,
modules, openFolder, settings, singleModule, plus, android, codeBlocks,
linux, xcode, visualStudio, clion;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Icons)
};
const Icons& getIcons();

View File

@ -0,0 +1,251 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_JucerTreeViewBase.h"
#include "../../Project/UI/jucer_ProjectContentComponent.h"
//==============================================================================
void TreePanelBase::setRoot (std::unique_ptr<JucerTreeViewBase> root)
{
rootItem = std::move (root);
tree.setRootItem (rootItem.get());
tree.getRootItem()->setOpen (true);
if (project != nullptr)
{
if (auto treeOpenness = project->getStoredProperties().getXmlValue (opennessStateKey))
{
tree.restoreOpennessState (*treeOpenness, true);
for (int i = tree.getNumSelectedItems(); --i >= 0;)
if (auto item = dynamic_cast<JucerTreeViewBase*> (tree.getSelectedItem (i)))
item->cancelDelayedSelectionTimer();
}
}
}
void TreePanelBase::saveOpenness()
{
if (project != nullptr)
{
std::unique_ptr<XmlElement> opennessState (tree.getOpennessState (true));
if (opennessState != nullptr)
project->getStoredProperties().setValue (opennessStateKey, opennessState.get());
else
project->getStoredProperties().removeValue (opennessStateKey);
}
}
//==============================================================================
JucerTreeViewBase::JucerTreeViewBase()
{
setLinesDrawnForSubItems (false);
setDrawsInLeftMargin (true);
}
void JucerTreeViewBase::refreshSubItems()
{
WholeTreeOpennessRestorer wtor (*this);
clearSubItems();
addSubItems();
}
Font JucerTreeViewBase::getFont() const
{
return Font ((float) getItemHeight() * 0.6f);
}
void JucerTreeViewBase::paintOpenCloseButton (Graphics& g, const Rectangle<float>& area, Colour /*backgroundColour*/, bool isMouseOver)
{
g.setColour (getOwnerView()->findColour (isSelected() ? defaultHighlightedTextColourId : treeIconColourId));
TreeViewItem::paintOpenCloseButton (g, area, getOwnerView()->findColour (defaultIconColourId), isMouseOver);
}
void JucerTreeViewBase::paintIcon (Graphics& g, Rectangle<float> area)
{
g.setColour (getContentColour (true));
getIcon().draw (g, area, isIconCrossedOut());
textX = roundToInt (area.getRight()) + 7;
}
void JucerTreeViewBase::paintItem (Graphics& g, int width, int height)
{
ignoreUnused (width, height);
auto bounds = g.getClipBounds().withY (0).withHeight (height).toFloat();
g.setColour (getOwnerView()->findColour (treeIconColourId).withMultipliedAlpha (0.4f));
g.fillRect (bounds.removeFromBottom (0.5f).reduced (5, 0));
}
Colour JucerTreeViewBase::getContentColour (bool isIcon) const
{
if (isMissing()) return Colours::red;
if (isSelected()) return getOwnerView()->findColour (defaultHighlightedTextColourId);
if (hasWarnings()) return getOwnerView()->findColour (defaultHighlightColourId);
return getOwnerView()->findColour (isIcon ? treeIconColourId : defaultTextColourId);
}
void JucerTreeViewBase::paintContent (Graphics& g, Rectangle<int> area)
{
g.setFont (getFont());
g.setColour (getContentColour (false));
g.drawFittedText (getDisplayName(), area, Justification::centredLeft, 1, 1.0f);
}
std::unique_ptr<Component> JucerTreeViewBase::createItemComponent()
{
return std::make_unique<TreeItemComponent> (*this);
}
//==============================================================================
class RenameTreeItemCallback : public ModalComponentManager::Callback
{
public:
RenameTreeItemCallback (JucerTreeViewBase& ti, Component& parent, const Rectangle<int>& bounds)
: item (ti)
{
ed.setMultiLine (false, false);
ed.setPopupMenuEnabled (false);
ed.setSelectAllWhenFocused (true);
ed.setFont (item.getFont());
ed.onReturnKey = [this] { ed.exitModalState (1); };
ed.onEscapeKey = [this] { ed.exitModalState (0); };
ed.onFocusLost = [this] { ed.exitModalState (0); };
ed.setText (item.getRenamingName());
ed.setBounds (bounds);
parent.addAndMakeVisible (ed);
ed.enterModalState (true, this);
}
void modalStateFinished (int resultCode) override
{
if (resultCode != 0)
item.setName (ed.getText());
}
private:
struct RenameEditor : public TextEditor
{
void inputAttemptWhenModal() override { exitModalState (0); }
};
RenameEditor ed;
JucerTreeViewBase& item;
JUCE_DECLARE_NON_COPYABLE (RenameTreeItemCallback)
};
void JucerTreeViewBase::showRenameBox()
{
Rectangle<int> r (getItemPosition (true));
r.setLeft (r.getX() + textX);
r.setHeight (getItemHeight());
new RenameTreeItemCallback (*this, *getOwnerView(), r);
}
void JucerTreeViewBase::itemClicked (const MouseEvent& e)
{
if (e.mods.isPopupMenu())
{
if (getOwnerView()->getNumSelectedItems() > 1)
showMultiSelectionPopupMenu (e.getMouseDownScreenPosition());
else
showPopupMenu (e.getMouseDownScreenPosition());
}
else if (isSelected())
{
itemSelectionChanged (true);
}
}
static void treeViewMenuItemChosen (int resultCode, WeakReference<JucerTreeViewBase> item)
{
if (item != nullptr)
item->handlePopupMenuResult (resultCode);
}
void JucerTreeViewBase::launchPopupMenu (PopupMenu& m, Point<int> p)
{
m.showMenuAsync (PopupMenu::Options().withTargetScreenArea ({ p.x, p.y, 1, 1 }),
ModalCallbackFunction::create (treeViewMenuItemChosen, WeakReference<JucerTreeViewBase> (this)));
}
ProjectContentComponent* JucerTreeViewBase::getProjectContentComponent() const
{
for (Component* c = getOwnerView(); c != nullptr; c = c->getParentComponent())
if (ProjectContentComponent* pcc = dynamic_cast<ProjectContentComponent*> (c))
return pcc;
return nullptr;
}
//==============================================================================
class JucerTreeViewBase::ItemSelectionTimer : public Timer
{
public:
explicit ItemSelectionTimer (JucerTreeViewBase& tvb) : owner (tvb) {}
void timerCallback() override { owner.invokeShowDocument(); }
private:
JucerTreeViewBase& owner;
JUCE_DECLARE_NON_COPYABLE (ItemSelectionTimer)
};
void JucerTreeViewBase::itemSelectionChanged (bool isNowSelected)
{
if (isNowSelected)
{
delayedSelectionTimer.reset (new ItemSelectionTimer (*this));
delayedSelectionTimer->startTimer (getMillisecsAllowedForDragGesture());
}
else
{
cancelDelayedSelectionTimer();
}
}
void JucerTreeViewBase::invokeShowDocument()
{
cancelDelayedSelectionTimer();
showDocument();
}
void JucerTreeViewBase::itemDoubleClicked (const MouseEvent&)
{
invokeShowDocument();
}
void JucerTreeViewBase::cancelDelayedSelectionTimer()
{
delayedSelectionTimer.reset();
}

View File

@ -0,0 +1,249 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
class ProjectContentComponent;
class Project;
//==============================================================================
class JucerTreeViewBase : public TreeViewItem,
public TooltipClient
{
public:
JucerTreeViewBase();
~JucerTreeViewBase() override = default;
int getItemWidth() const override { return -1; }
int getItemHeight() const override { return 25; }
void paintOpenCloseButton (Graphics&, const Rectangle<float>& area, Colour backgroundColour, bool isMouseOver) override;
void paintItem (Graphics& g, int width, int height) override;
void itemClicked (const MouseEvent& e) override;
void itemSelectionChanged (bool isNowSelected) override;
void itemDoubleClicked (const MouseEvent&) override;
std::unique_ptr<Component> createItemComponent() override;
String getTooltip() override { return {}; }
String getAccessibilityName() override { return getDisplayName(); }
void cancelDelayedSelectionTimer();
//==============================================================================
virtual bool isRoot() const { return false; }
virtual Font getFont() const;
virtual String getRenamingName() const = 0;
virtual String getDisplayName() const = 0;
virtual void setName (const String& newName) = 0;
virtual bool isMissing() const = 0;
virtual bool hasWarnings() const { return false; }
virtual Icon getIcon() const = 0;
virtual bool isIconCrossedOut() const { return false; }
virtual void paintIcon (Graphics& g, Rectangle<float> area);
virtual void paintContent (Graphics& g, Rectangle<int> area);
virtual int getRightHandButtonSpace() { return 0; }
virtual Colour getContentColour (bool isIcon) const;
virtual int getMillisecsAllowedForDragGesture() { return 120; }
virtual File getDraggableFile() const { return {}; }
void refreshSubItems();
void showRenameBox();
virtual void deleteItem() {}
virtual void deleteAllSelectedItems() {}
virtual void showDocument() {}
virtual void showMultiSelectionPopupMenu (Point<int>) {}
virtual void showPopupMenu (Point<int>) {}
virtual void showAddMenu (Point<int>) {}
virtual void handlePopupMenuResult (int) {}
virtual void setSearchFilter (const String&) {}
void launchPopupMenu (PopupMenu&, Point<int>); // runs asynchronously, and produces a callback to handlePopupMenuResult().
//==============================================================================
// To handle situations where an item gets deleted before openness is
// restored for it, this OpennessRestorer keeps only a pointer to the
// topmost tree item.
struct WholeTreeOpennessRestorer : public OpennessRestorer
{
WholeTreeOpennessRestorer (TreeViewItem& item) : OpennessRestorer (getTopLevelItem (item))
{}
private:
static TreeViewItem& getTopLevelItem (TreeViewItem& item)
{
if (TreeViewItem* const p = item.getParentItem())
return getTopLevelItem (*p);
return item;
}
};
int textX = 0;
protected:
ProjectContentComponent* getProjectContentComponent() const;
virtual void addSubItems() {}
private:
class ItemSelectionTimer;
friend class ItemSelectionTimer;
std::unique_ptr<Timer> delayedSelectionTimer;
void invokeShowDocument();
JUCE_DECLARE_WEAK_REFERENCEABLE (JucerTreeViewBase)
};
//==============================================================================
class TreePanelBase : public Component
{
public:
TreePanelBase (const Project* p, const String& treeviewID)
: project (p), opennessStateKey (treeviewID)
{
addAndMakeVisible (tree);
tree.setRootItemVisible (true);
tree.setDefaultOpenness (true);
tree.setColour (TreeView::backgroundColourId, Colours::transparentBlack);
tree.setIndentSize (14);
tree.getViewport()->setScrollBarThickness (6);
tree.addMouseListener (this, true);
}
~TreePanelBase() override
{
tree.setRootItem (nullptr);
}
void setRoot (std::unique_ptr<JucerTreeViewBase>);
void saveOpenness();
virtual void deleteSelectedItems()
{
if (rootItem != nullptr)
rootItem->deleteAllSelectedItems();
}
void setEmptyTreeMessage (const String& newMessage)
{
if (emptyTreeMessage != newMessage)
{
emptyTreeMessage = newMessage;
repaint();
}
}
static void drawEmptyPanelMessage (Component& comp, Graphics& g, const String& message)
{
const int fontHeight = 13;
const Rectangle<int> area (comp.getLocalBounds());
g.setColour (comp.findColour (defaultTextColourId));
g.setFont ((float) fontHeight);
g.drawFittedText (message, area.reduced (4, 2), Justification::centred, area.getHeight() / fontHeight);
}
void paint (Graphics& g) override
{
if (emptyTreeMessage.isNotEmpty() && (rootItem == nullptr || rootItem->getNumSubItems() == 0))
drawEmptyPanelMessage (*this, g, emptyTreeMessage);
}
void resized() override
{
tree.setBounds (getAvailableBounds());
}
Rectangle<int> getAvailableBounds() const
{
return Rectangle<int> (0, 2, getWidth() - 2, getHeight() - 2);
}
void mouseDown (const MouseEvent& e) override
{
if (e.eventComponent == &tree)
{
tree.clearSelectedItems();
if (e.mods.isRightButtonDown())
rootItem->showPopupMenu (e.getMouseDownScreenPosition());
}
}
const Project* project;
TreeView tree;
std::unique_ptr<JucerTreeViewBase> rootItem;
private:
String opennessStateKey, emptyTreeMessage;
};
//==============================================================================
class TreeItemComponent : public Component
{
public:
TreeItemComponent (JucerTreeViewBase& i) : item (&i)
{
setAccessible (false);
setInterceptsMouseClicks (false, true);
item->textX = iconWidth;
}
void paint (Graphics& g) override
{
if (item == nullptr)
return;
auto bounds = getLocalBounds().toFloat();
auto iconBounds = bounds.removeFromLeft ((float) iconWidth).reduced (7, 5);
bounds.removeFromRight ((float) buttons.size() * bounds.getHeight());
item->paintIcon (g, iconBounds);
item->paintContent (g, bounds.toNearestInt());
}
void resized() override
{
auto r = getLocalBounds();
for (int i = buttons.size(); --i >= 0;)
buttons.getUnchecked (i)->setBounds (r.removeFromRight (r.getHeight()));
}
void addRightHandButton (Component* button)
{
buttons.add (button);
addAndMakeVisible (button);
}
WeakReference<JucerTreeViewBase> item;
OwnedArray<Component> buttons;
const int iconWidth = 25;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TreeItemComponent)
};

View File

@ -0,0 +1,589 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_ProjucerLookAndFeel.h"
#include "../../Project/UI/jucer_ProjectContentComponent.h"
//==============================================================================
ProjucerLookAndFeel::ProjucerLookAndFeel()
{
setupColours();
}
ProjucerLookAndFeel::~ProjucerLookAndFeel() {}
void ProjucerLookAndFeel::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown)
{
const auto area = button.getActiveArea();
auto backgroundColour = findColour (button.isFrontTab() ? secondaryBackgroundColourId
: inactiveTabBackgroundColourId);
g.setColour (backgroundColour);
g.fillRect (area);
const auto alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f;
auto textColour = findColour (defaultTextColourId).withMultipliedAlpha (alpha);
auto iconColour = findColour (button.isFrontTab() ? activeTabIconColourId
: inactiveTabIconColourId);
auto isProjectTab = button.getName() == ProjectContentComponent::getProjectTabName();
if (isProjectTab)
{
auto icon = Icon (getIcons().closedFolder,
iconColour.withMultipliedAlpha (alpha));
auto isSingleTab = (button.getTabbedButtonBar().getNumTabs() == 1);
if (isSingleTab)
{
auto activeArea = button.getActiveArea().reduced (5);
activeArea.removeFromLeft (15);
icon.draw (g, activeArea.removeFromLeft (activeArea.getHeight()).toFloat(), false);
activeArea.removeFromLeft (10);
g.setColour (textColour);
g.drawFittedText (ProjectContentComponent::getProjectTabName(),
activeArea, Justification::centredLeft, 1);
}
else
{
icon.draw (g, button.getTextArea().reduced (8, 8).toFloat(), false);
}
}
else
{
TextLayout textLayout;
LookAndFeel_V3::createTabTextLayout (button, (float) area.getWidth(), (float) area.getHeight(), textColour, textLayout);
textLayout.draw (g, button.getTextArea().toFloat());
}
}
int ProjucerLookAndFeel::getTabButtonBestWidth (TabBarButton& button, int)
{
if (TabbedButtonBar* bar = button.findParentComponentOfClass<TabbedButtonBar>())
return bar->getWidth() / bar->getNumTabs();
return 120;
}
void ProjucerLookAndFeel::drawPropertyComponentLabel (Graphics& g, int width, int height, PropertyComponent& component)
{
ignoreUnused (width);
g.setColour (component.findColour (defaultTextColourId)
.withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f));
auto textWidth = getTextWidthForPropertyComponent (&component);
g.setFont (getPropertyComponentFont());
g.drawFittedText (component.getName(), 0, 0, textWidth - 5, height, Justification::centredLeft, 5, 1.0f);
}
Rectangle<int> ProjucerLookAndFeel::getPropertyComponentContentPosition (PropertyComponent& component)
{
const auto textW = getTextWidthForPropertyComponent (&component);
return { textW, 0, component.getWidth() - textW, component.getHeight() - 1 };
}
void ProjucerLookAndFeel::drawButtonBackground (Graphics& g,
Button& button,
const Colour& backgroundColour,
bool isMouseOverButton,
bool isButtonDown)
{
const auto cornerSize = button.findParentComponentOfClass<PropertyComponent>() != nullptr ? 0.0f : 3.0f;
const auto bounds = button.getLocalBounds().toFloat();
auto baseColour = backgroundColour.withMultipliedAlpha (button.isEnabled() ? 1.0f : 0.5f);
if (isButtonDown || isMouseOverButton)
baseColour = baseColour.contrasting (isButtonDown ? 0.2f : 0.05f);
g.setColour (baseColour);
if (button.isConnectedOnLeft() || button.isConnectedOnRight())
{
Path path;
path.addRoundedRectangle (bounds.getX(), bounds.getY(),
bounds.getWidth(), bounds.getHeight(),
cornerSize, cornerSize,
! button.isConnectedOnLeft(),
! button.isConnectedOnRight(),
! button.isConnectedOnLeft(),
! button.isConnectedOnRight());
g.fillPath (path);
}
else
{
g.fillRoundedRectangle (bounds, cornerSize);
}
}
void ProjucerLookAndFeel::drawButtonText (Graphics& g, TextButton& button, bool isMouseOverButton, bool isButtonDown)
{
ignoreUnused (isMouseOverButton, isButtonDown);
g.setFont (getTextButtonFont (button, button.getHeight()));
g.setColour (button.findColour (button.getToggleState() ? TextButton::textColourOnId
: TextButton::textColourOffId)
.withMultipliedAlpha (button.isEnabled() ? 1.0f
: 0.5f));
auto xIndent = jmin (8, button.getWidth() / 10);
auto yIndent = jmin (3, button.getHeight() / 6);
auto textBounds = button.getLocalBounds().reduced (xIndent, yIndent);
g.drawFittedText (button.getButtonText(), textBounds, Justification::centred, 3, 1.0f);
}
void ProjucerLookAndFeel::drawToggleButton (Graphics& g, ToggleButton& button, bool isMouseOverButton, bool isButtonDown)
{
ignoreUnused (isMouseOverButton, isButtonDown);
if (! button.isEnabled())
g.setOpacity (0.5f);
bool isTextEmpty = button.getButtonText().isEmpty();
bool isPropertyComponentChild = (dynamic_cast<BooleanPropertyComponent*> (button.getParentComponent()) != nullptr
|| dynamic_cast<MultiChoicePropertyComponent*> (button.getParentComponent()) != nullptr);
auto bounds = button.getLocalBounds();
auto sideLength = isPropertyComponentChild ? 25 : bounds.getHeight();
auto rectBounds = isTextEmpty ? bounds
: bounds.removeFromLeft (jmin (sideLength, bounds.getWidth() / 3));
rectBounds = rectBounds.withSizeKeepingCentre (sideLength, sideLength).reduced (4);
g.setColour (button.findColour (ToggleButton::tickDisabledColourId));
g.drawRoundedRectangle (rectBounds.toFloat(), 2.0f, 1.0f);
if (button.getToggleState())
{
g.setColour (button.findColour (ToggleButton::tickColourId));
const auto tick = getTickShape (0.75f);
g.fillPath (tick, tick.getTransformToScaleToFit (rectBounds.reduced (2).toFloat(), false));
}
if (! isTextEmpty)
{
bounds.removeFromLeft (5);
const auto fontSize = jmin (15.0f, (float) button.getHeight() * 0.75f);
g.setFont (fontSize);
g.setColour (isPropertyComponentChild ? findColour (widgetTextColourId)
: button.findColour (ToggleButton::textColourId));
g.drawFittedText (button.getButtonText(), bounds, Justification::centredLeft, 2);
}
}
void ProjucerLookAndFeel::fillTextEditorBackground (Graphics& g, int width, int height, TextEditor& textEditor)
{
g.setColour (textEditor.findColour (TextEditor::backgroundColourId));
g.fillRect (0, 0, width, height);
g.setColour (textEditor.findColour (TextEditor::outlineColourId));
g.drawHorizontalLine (height - 1, 0.0f, static_cast<float> (width));
}
void ProjucerLookAndFeel::layoutFileBrowserComponent (FileBrowserComponent& browserComp,
DirectoryContentsDisplayComponent* fileListComponent,
FilePreviewComponent* previewComp,
ComboBox* currentPathBox,
TextEditor* filenameBox,
Button* goUpButton)
{
const auto sectionHeight = 22;
const auto buttonWidth = 50;
auto b = browserComp.getLocalBounds().reduced (20, 5);
auto topSlice = b.removeFromTop (sectionHeight);
auto bottomSlice = b.removeFromBottom (sectionHeight);
currentPathBox->setBounds (topSlice.removeFromLeft (topSlice.getWidth() - buttonWidth));
currentPathBox->setColour (ComboBox::backgroundColourId, findColour (backgroundColourId));
currentPathBox->setColour (ComboBox::textColourId, findColour (defaultTextColourId));
currentPathBox->setColour (ComboBox::arrowColourId, findColour (defaultTextColourId));
topSlice.removeFromLeft (6);
goUpButton->setBounds (topSlice);
bottomSlice.removeFromLeft (50);
filenameBox->setBounds (bottomSlice);
filenameBox->setColour (TextEditor::backgroundColourId, findColour (backgroundColourId));
filenameBox->setColour (TextEditor::textColourId, findColour (defaultTextColourId));
filenameBox->setColour (TextEditor::outlineColourId, findColour (defaultTextColourId));
filenameBox->applyFontToAllText (filenameBox->getFont());
if (previewComp != nullptr)
previewComp->setBounds (b.removeFromRight (b.getWidth() / 3));
if (auto listAsComp = dynamic_cast<Component*> (fileListComponent))
listAsComp->setBounds (b.reduced (0, 10));
}
void ProjucerLookAndFeel::drawFileBrowserRow (Graphics& g, int width, int height,
const File& file, const String& filename, Image* icon,
const String& fileSizeDescription,
const String& fileTimeDescription,
bool isDirectory, bool isItemSelected,
int itemIndex, DirectoryContentsDisplayComponent& dcc)
{
if (auto fileListComp = dynamic_cast<Component*> (&dcc))
{
fileListComp->setColour (DirectoryContentsDisplayComponent::textColourId,
findColour (isItemSelected ? defaultHighlightedTextColourId : defaultTextColourId));
fileListComp->setColour (DirectoryContentsDisplayComponent::highlightColourId,
findColour (defaultHighlightColourId).withAlpha (0.75f));
}
LookAndFeel_V2::drawFileBrowserRow (g, width, height, file, filename, icon,
fileSizeDescription, fileTimeDescription,
isDirectory, isItemSelected, itemIndex, dcc);
}
void ProjucerLookAndFeel::drawCallOutBoxBackground (CallOutBox&, Graphics& g, const Path& path, Image&)
{
g.setColour (findColour (secondaryBackgroundColourId));
g.fillPath (path);
g.setColour (findColour (userButtonBackgroundColourId));
g.strokePath (path, PathStrokeType (2.0f));
}
void ProjucerLookAndFeel::drawMenuBarBackground (Graphics& g, int width, int height,
bool, MenuBarComponent& menuBar)
{
const auto colour = menuBar.findColour (backgroundColourId).withAlpha (0.75f);
Rectangle<int> r (width, height);
g.setColour (colour.contrasting (0.15f));
g.fillRect (r.removeFromTop (1));
g.fillRect (r.removeFromBottom (1));
g.setGradientFill (ColourGradient (colour, 0, 0, colour.darker (0.2f), 0, (float)height, false));
g.fillRect (r);
}
void ProjucerLookAndFeel::drawMenuBarItem (Graphics& g, int width, int height,
int itemIndex, const String& itemText,
bool isMouseOverItem, bool isMenuOpen,
bool /*isMouseOverBar*/, MenuBarComponent& menuBar)
{
if (! menuBar.isEnabled())
{
g.setColour (menuBar.findColour (defaultTextColourId)
.withMultipliedAlpha (0.5f));
}
else if (isMenuOpen || isMouseOverItem)
{
g.fillAll (menuBar.findColour (defaultHighlightColourId).withAlpha (0.75f));
g.setColour (menuBar.findColour (defaultHighlightedTextColourId));
}
else
{
g.setColour (menuBar.findColour (defaultTextColourId));
}
g.setFont (getMenuBarFont (menuBar, itemIndex, itemText));
g.drawFittedText (itemText, 0, 0, width, height, Justification::centred, 1);
}
void ProjucerLookAndFeel::drawResizableFrame (Graphics& g, int w, int h, const BorderSize<int>& border)
{
ignoreUnused (g, w, h, border);
}
void ProjucerLookAndFeel::drawComboBox (Graphics& g, int width, int height, bool,
int, int, int, int, ComboBox& box)
{
const auto cornerSize = box.findParentComponentOfClass<ChoicePropertyComponent>() != nullptr ? 0.0f : 1.5f;
Rectangle<int> boxBounds (0, 0, width, height);
auto isChoiceCompChild = (box.findParentComponentOfClass<ChoicePropertyComponent>() != nullptr);
if (isChoiceCompChild)
{
box.setColour (ComboBox::textColourId, findColour (widgetTextColourId));
g.setColour (findColour (widgetBackgroundColourId));
g.fillRect (boxBounds);
auto arrowZone = boxBounds.removeFromRight (boxBounds.getHeight()).reduced (0, 2).toFloat();
g.setColour (Colours::black);
g.fillPath (getChoiceComponentArrowPath (arrowZone));
}
else
{
g.setColour (box.findColour (ComboBox::outlineColourId));
g.drawRoundedRectangle (boxBounds.toFloat().reduced (0.5f, 0.5f), cornerSize, 1.0f);
auto arrowZone = boxBounds.removeFromRight (boxBounds.getHeight()).toFloat();
g.setColour (box.findColour (ComboBox::arrowColourId).withAlpha ((box.isEnabled() ? 0.9f : 0.2f)));
g.fillPath (getArrowPath (arrowZone, 2, true, Justification::centred));
}
}
void ProjucerLookAndFeel::drawTreeviewPlusMinusBox (Graphics& g, const Rectangle<float>& area,
Colour, bool isOpen, bool /**isMouseOver*/)
{
g.strokePath (getArrowPath (area, isOpen ? 2 : 1, false, Justification::centredRight), PathStrokeType (2.0f));
}
void ProjucerLookAndFeel::drawProgressBar (Graphics& g, ProgressBar& progressBar,
int width, int height, double progress, const String& textToShow)
{
ignoreUnused (width, height, progress);
const auto background = progressBar.findColour (ProgressBar::backgroundColourId);
const auto foreground = progressBar.findColour (defaultButtonBackgroundColourId);
const auto sideLength = jmin (width, height);
auto barBounds = progressBar.getLocalBounds().withSizeKeepingCentre (sideLength, sideLength).reduced (1).toFloat();
auto rotationInDegrees = static_cast<float> ((Time::getMillisecondCounter() / 10) % 360);
auto normalisedRotation = rotationInDegrees / 360.0f;
const auto rotationOffset = 22.5f;
const auto maxRotation = 315.0f;
auto startInDegrees = rotationInDegrees;
auto endInDegrees = startInDegrees + rotationOffset;
if (normalisedRotation >= 0.25f && normalisedRotation < 0.5f)
{
const auto rescaledRotation = (normalisedRotation * 4.0f) - 1.0f;
endInDegrees = startInDegrees + rotationOffset + (maxRotation * rescaledRotation);
}
else if (normalisedRotation >= 0.5f && normalisedRotation <= 1.0f)
{
endInDegrees = startInDegrees + rotationOffset + maxRotation;
const auto rescaledRotation = 1.0f - ((normalisedRotation * 2.0f) - 1.0f);
startInDegrees = endInDegrees - rotationOffset - (maxRotation * rescaledRotation);
}
g.setColour (background);
Path arcPath2;
arcPath2.addCentredArc (barBounds.getCentreX(),
barBounds.getCentreY(),
barBounds.getWidth() * 0.5f,
barBounds.getHeight() * 0.5f, 0.0f,
0.0f,
MathConstants<float>::twoPi,
true);
g.strokePath (arcPath2, PathStrokeType (2.0f));
g.setColour (foreground);
Path arcPath;
arcPath.addCentredArc (barBounds.getCentreX(),
barBounds.getCentreY(),
barBounds.getWidth() * 0.5f,
barBounds.getHeight() * 0.5f,
0.0f,
degreesToRadians (startInDegrees),
degreesToRadians (endInDegrees),
true);
arcPath.applyTransform (AffineTransform::rotation (normalisedRotation * MathConstants<float>::pi * 2.25f,
barBounds.getCentreX(), barBounds.getCentreY()));
g.strokePath (arcPath, PathStrokeType (2.0f));
if (textToShow.isNotEmpty())
{
g.setColour (progressBar.findColour (TextButton::textColourOffId));
g.setFont (Font (12.0f, 2));
g.drawText (textToShow, barBounds, Justification::centred, false);
}
}
//==============================================================================
Path ProjucerLookAndFeel::getArrowPath (Rectangle<float> arrowZone, const int direction,
bool filled, const Justification justification)
{
auto w = jmin (arrowZone.getWidth(), (direction == 0 || direction == 2) ? 8.0f : filled ? 5.0f : 8.0f);
auto h = jmin (arrowZone.getHeight(), (direction == 0 || direction == 2) ? 5.0f : filled ? 8.0f : 5.0f);
if (justification == Justification::centred)
{
arrowZone.reduce ((arrowZone.getWidth() - w) / 2, (arrowZone.getHeight() - h) / 2);
}
else if (justification == Justification::centredRight)
{
arrowZone.removeFromLeft (arrowZone.getWidth() - w);
arrowZone.reduce (0, (arrowZone.getHeight() - h) / 2);
}
else if (justification == Justification::centredLeft)
{
arrowZone.removeFromRight (arrowZone.getWidth() - w);
arrowZone.reduce (0, (arrowZone.getHeight() - h) / 2);
}
else
{
jassertfalse; // currently only supports centred justifications
}
Path path;
path.startNewSubPath (arrowZone.getX(), arrowZone.getBottom());
path.lineTo (arrowZone.getCentreX(), arrowZone.getY());
path.lineTo (arrowZone.getRight(), arrowZone.getBottom());
if (filled)
path.closeSubPath();
path.applyTransform (AffineTransform::rotation ((float) direction * MathConstants<float>::halfPi,
arrowZone.getCentreX(), arrowZone.getCentreY()));
return path;
}
Path ProjucerLookAndFeel::getChoiceComponentArrowPath (Rectangle<float> arrowZone)
{
auto topBounds = arrowZone.removeFromTop (arrowZone.getHeight() * 0.5f);
auto bottomBounds = arrowZone;
auto topArrow = getArrowPath (topBounds, 0, true, Justification::centred);
auto bottomArrow = getArrowPath (bottomBounds, 2, true, Justification::centred);
topArrow.addPath (bottomArrow);
return topArrow;
}
//==============================================================================
void ProjucerLookAndFeel::setupColours()
{
auto& colourScheme = getCurrentColourScheme();
if (colourScheme == getDarkColourScheme() || colourScheme == getProjucerDarkColourScheme())
{
setColour (backgroundColourId, Colour (0xff323e44));
setColour (secondaryBackgroundColourId, Colour (0xff263238));
setColour (defaultTextColourId, Colours::white);
setColour (widgetTextColourId, Colours::white);
setColour (defaultButtonBackgroundColourId, Colour (0xffa45c94));
setColour (secondaryButtonBackgroundColourId, Colours::black);
setColour (userButtonBackgroundColourId, Colour (0xffa45c94));
setColour (defaultIconColourId, Colours::white);
setColour (treeIconColourId, Colour (0xffa9a9a9));
setColour (defaultHighlightColourId, Colour (0xffe0ec65));
setColour (defaultHighlightedTextColourId, Colours::black);
setColour (codeEditorLineNumberColourId, Colour (0xffaaaaaa));
setColour (activeTabIconColourId, Colours::white);
setColour (inactiveTabBackgroundColourId, Colour (0xff181f22));
setColour (inactiveTabIconColourId, Colour (0xffa9a9a9));
setColour (contentHeaderBackgroundColourId, Colours::black);
setColour (widgetBackgroundColourId, Colour (0xff495358));
setColour (secondaryWidgetBackgroundColourId, Colour (0xff303b41));
colourScheme = getProjucerDarkColourScheme();
}
else if (colourScheme == getGreyColourScheme())
{
setColour (backgroundColourId, Colour (0xff505050));
setColour (secondaryBackgroundColourId, Colour (0xff424241));
setColour (defaultTextColourId, Colours::white);
setColour (widgetTextColourId, Colours::black);
setColour (defaultButtonBackgroundColourId, Colour (0xff26ba90));
setColour (secondaryButtonBackgroundColourId, Colours::black);
setColour (userButtonBackgroundColourId, Colour (0xff26ba90));
setColour (defaultIconColourId, Colours::white);
setColour (treeIconColourId, Colour (0xffa9a9a9));
setColour (defaultHighlightColourId, Colour (0xffe0ec65));
setColour (defaultHighlightedTextColourId, Colours::black);
setColour (codeEditorLineNumberColourId, Colour (0xffaaaaaa));
setColour (activeTabIconColourId, Colours::white);
setColour (inactiveTabBackgroundColourId, Colour (0xff373737));
setColour (inactiveTabIconColourId, Colour (0xffa9a9a9));
setColour (contentHeaderBackgroundColourId, Colours::black);
setColour (widgetBackgroundColourId, Colours::white);
setColour (secondaryWidgetBackgroundColourId, Colour (0xffdddddd));
}
else if (colourScheme == getLightColourScheme())
{
setColour (backgroundColourId, Colour (0xffefefef));
setColour (secondaryBackgroundColourId, Colour (0xfff9f9f9));
setColour (defaultTextColourId, Colours::black);
setColour (widgetTextColourId, Colours::black);
setColour (defaultButtonBackgroundColourId, Colour (0xff42a2c8));
setColour (secondaryButtonBackgroundColourId, Colour (0xffa1c677));
setColour (userButtonBackgroundColourId, Colour (0xff42a2c8));
setColour (defaultIconColourId, Colours::white);
setColour (treeIconColourId, Colour (0xffa9a9a9));
setColour (defaultHighlightColourId, Colours::orange);
setColour (defaultHighlightedTextColourId, Colour (0xff585656));
setColour (codeEditorLineNumberColourId, Colour (0xff888888));
setColour (activeTabIconColourId, Colour (0xff42a2c8));
setColour (inactiveTabBackgroundColourId, Colour (0xffd5d5d5));
setColour (inactiveTabIconColourId, Colour (0xffa9a9a9));
setColour (contentHeaderBackgroundColourId, Colour (0xff42a2c8));
setColour (widgetBackgroundColourId, Colours::white);
setColour (secondaryWidgetBackgroundColourId, Colour (0xfff4f4f4));
}
setColour (Label::textColourId, findColour (defaultTextColourId));
setColour (Label::textWhenEditingColourId, findColour (widgetTextColourId));
setColour (TextEditor::highlightColourId, findColour (defaultHighlightColourId).withAlpha (0.75f));
setColour (TextEditor::highlightedTextColourId, findColour (defaultHighlightedTextColourId));
setColour (TextEditor::outlineColourId, Colours::transparentBlack);
setColour (TextEditor::focusedOutlineColourId, Colours::transparentBlack);
setColour (TextEditor::backgroundColourId, findColour (widgetBackgroundColourId));
setColour (TextEditor::textColourId, findColour (widgetTextColourId));
setColour (TextButton::buttonColourId, findColour (defaultButtonBackgroundColourId));
setColour (ScrollBar::ColourIds::thumbColourId, Colour (0xffd0d8e0));
setColour (TextPropertyComponent::outlineColourId, Colours::transparentBlack);
setColour (TextPropertyComponent::backgroundColourId, findColour (widgetBackgroundColourId));
setColour (TextPropertyComponent::textColourId, findColour (widgetTextColourId));
setColour (BooleanPropertyComponent::outlineColourId, Colours::transparentBlack);
setColour (BooleanPropertyComponent::backgroundColourId, findColour (widgetBackgroundColourId));
setColour (ToggleButton::tickDisabledColourId, Colour (0xffa9a9a9));
setColour (ToggleButton::tickColourId, findColour (defaultButtonBackgroundColourId).withMultipliedBrightness(1.3f));
setColour (CodeEditorComponent::backgroundColourId, findColour (secondaryBackgroundColourId));
setColour (CodeEditorComponent::lineNumberTextId, findColour (codeEditorLineNumberColourId));
setColour (CodeEditorComponent::lineNumberBackgroundId, findColour (backgroundColourId));
setColour (CodeEditorComponent::highlightColourId, findColour (defaultHighlightColourId).withAlpha (0.5f));
setColour (CaretComponent::caretColourId, findColour (defaultButtonBackgroundColourId));
setColour (TreeView::selectedItemBackgroundColourId, findColour (defaultHighlightColourId));
setColour (PopupMenu::highlightedBackgroundColourId, findColour (defaultHighlightColourId).withAlpha (0.75f));
setColour (PopupMenu::highlightedTextColourId, findColour (defaultHighlightedTextColourId));
setColour (0x1000440, /*LassoComponent::lassoFillColourId*/ findColour (defaultHighlightColourId).withAlpha (0.3f));
}

View File

@ -0,0 +1,100 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
//==============================================================================
class ProjucerLookAndFeel : public LookAndFeel_V4
{
public:
ProjucerLookAndFeel();
~ProjucerLookAndFeel() override;
void drawTabButton (TabBarButton& button, Graphics&, bool isMouseOver, bool isMouseDown) override;
int getTabButtonBestWidth (TabBarButton&, int tabDepth) override;
void drawTabAreaBehindFrontButton (TabbedButtonBar&, Graphics&, int, int) override {}
void drawPropertyComponentBackground (Graphics&, int, int, PropertyComponent&) override {}
void drawPropertyComponentLabel (Graphics&, int width, int height, PropertyComponent&) override;
Rectangle<int> getPropertyComponentContentPosition (PropertyComponent&) override;
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool isMouseOverButton, bool isButtonDown) override;
void drawButtonText (Graphics&, TextButton&, bool isMouseOverButton, bool isButtonDown) override;
void drawToggleButton (Graphics&, ToggleButton&, bool isMouseOverButton, bool isButtonDown) override;
void drawTextEditorOutline (Graphics&, int, int, TextEditor&) override {}
void fillTextEditorBackground (Graphics&, int width, int height, TextEditor&) override;
void layoutFileBrowserComponent (FileBrowserComponent&, DirectoryContentsDisplayComponent*,
FilePreviewComponent*, ComboBox* currentPathBox,
TextEditor* filenameBox,Button* goUpButton) override;
void drawFileBrowserRow (Graphics&, int width, int height, const File&, const String& filename, Image* icon,
const String& fileSizeDescription, const String& fileTimeDescription,
bool isDirectory, bool isItemSelected, int itemIndex, DirectoryContentsDisplayComponent&) override;
void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path&, Image&) override;
void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override;
void drawMenuBarItem (Graphics&, int width, int height,
int itemIndex, const String& itemText,
bool isMouseOverItem, bool isMenuOpen, bool isMouseOverBar,
MenuBarComponent&) override;
void drawResizableFrame (Graphics&, int w, int h, const BorderSize<int>&) override;
void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox&) override;
void drawTreeviewPlusMinusBox (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isItemOpen, bool isMouseOver) override;
void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) override;
//==============================================================================
static Path getArrowPath (Rectangle<float> arrowZone, const int direction,
const bool filled, const Justification justification);
static Path getChoiceComponentArrowPath (Rectangle<float> arrowZone);
static Font getPropertyComponentFont() { return { 14.0f, Font::FontStyleFlags::bold }; }
static int getTextWidthForPropertyComponent (PropertyComponent* pp) { return jmin (200, pp->getWidth() / 2); }
static ColourScheme getProjucerDarkColourScheme()
{
return { 0xff323e44, 0xff263238, 0xff323e44,
0xff8e989b, 0xffffffff, 0xffa45c94,
0xffffffff, 0xff181f22, 0xffffffff };
}
//==============================================================================
void setupColours();
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProjucerLookAndFeel)
};

View File

@ -0,0 +1,118 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#include "../../Application/jucer_Headers.h"
#include "jucer_SlidingPanelComponent.h"
//==============================================================================
struct SlidingPanelComponent::DotButton : public Button
{
DotButton (SlidingPanelComponent& sp, int pageIndex)
: Button (String()), owner (sp), index (pageIndex) {}
void paintButton (Graphics& g, bool /*isMouseOverButton*/, bool /*isButtonDown*/) override
{
g.setColour (findColour (defaultButtonBackgroundColourId));
const auto r = getLocalBounds().reduced (getWidth() / 4).toFloat();
if (index == owner.getCurrentTabIndex())
g.fillEllipse (r);
else
g.drawEllipse (r, 1.0f);
}
void clicked() override
{
owner.goToTab (index);
}
using Button::clicked;
SlidingPanelComponent& owner;
int index;
};
//==============================================================================
SlidingPanelComponent::SlidingPanelComponent()
: currentIndex (0), dotSize (20)
{
addAndMakeVisible (pageHolder);
}
SlidingPanelComponent::~SlidingPanelComponent()
{
}
SlidingPanelComponent::PageInfo::~PageInfo()
{
if (shouldDelete)
content.deleteAndZero();
}
void SlidingPanelComponent::addTab (const String& tabName,
Component* const contentComponent,
const bool deleteComponentWhenNotNeeded,
const int insertIndex)
{
PageInfo* page = new PageInfo();
pages.insert (insertIndex, page);
page->content = contentComponent;
page->dotButton.reset (new DotButton (*this, pages.indexOf (page)));
addAndMakeVisible (page->dotButton.get());
page->name = tabName;
page->shouldDelete = deleteComponentWhenNotNeeded;
pageHolder.addAndMakeVisible (contentComponent);
resized();
}
void SlidingPanelComponent::goToTab (int targetTabIndex)
{
currentIndex = targetTabIndex;
Desktop::getInstance().getAnimator()
.animateComponent (&pageHolder, pageHolder.getBounds().withX (-targetTabIndex * getWidth()),
1.0f, 600, false, 0.0, 0.0);
repaint();
}
void SlidingPanelComponent::resized()
{
pageHolder.setBounds (-currentIndex * getWidth(), pageHolder.getPosition().y,
getNumTabs() * getWidth(), getHeight());
Rectangle<int> content (getLocalBounds());
Rectangle<int> dotHolder = content.removeFromBottom (20 + dotSize)
.reduced ((content.getWidth() - dotSize * getNumTabs()) / 2, 10);
for (int i = 0; i < getNumTabs(); ++i)
pages.getUnchecked(i)->dotButton->setBounds (dotHolder.removeFromLeft (dotSize));
for (int i = pages.size(); --i >= 0;)
if (Component* c = pages.getUnchecked(i)->content)
c->setBounds (content.translated (i * content.getWidth(), 0));
}

View File

@ -0,0 +1,79 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#pragma once
#include "../../Application/jucer_Application.h"
//==============================================================================
class SlidingPanelComponent : public Component
{
public:
SlidingPanelComponent();
~SlidingPanelComponent() override;
/** Adds a new tab to the panel slider. */
void addTab (const String& tabName,
Component* contentComponent,
bool deleteComponentWhenNotNeeded,
int insertIndex = -1);
/** Gets rid of one of the tabs. */
void removeTab (int tabIndex);
/** Gets index of current tab. */
int getCurrentTabIndex() const noexcept { return currentIndex; }
/** Returns the number of tabs. */
int getNumTabs() const noexcept { return pages.size(); }
/** Animates the window to the desired tab. */
void goToTab (int targetTabIndex);
//==============================================================================
/** @internal */
void resized() override;
private:
struct DotButton;
friend struct DotButton;
struct PageInfo
{
~PageInfo();
Component::SafePointer<Component> content;
std::unique_ptr<DotButton> dotButton;
String name;
bool shouldDelete;
};
OwnedArray<PageInfo> pages;
Component pageHolder;
int currentIndex, dotSize;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SlidingPanelComponent)
};