@@ -14,7 +14,7 @@ ifeq ($(ARCH), lin) | |||
LDFLAGS += -rdynamic \ | |||
-lpthread -lGL -ldl \ | |||
$(shell pkg-config --libs gtk+-2.0) \ | |||
-Ldep/lib -lGLEW -lglfw -ljansson -lspeexdsp -lcurl -lzip -lrtaudio -lrtmidi | |||
-Ldep/lib -lGLEW -lglfw -ljansson -lspeexdsp -lcurl -lzip -lrtaudio -lrtmidi -lcrypto -lssl | |||
TARGET = Rack | |||
endif | |||
@@ -23,7 +23,7 @@ ifeq ($(ARCH), mac) | |||
CXXFLAGS += -DAPPLE -stdlib=libc++ | |||
LDFLAGS += -stdlib=libc++ -lpthread -ldl \ | |||
-framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo \ | |||
-Ldep/lib -lGLEW -lglfw -ljansson -lspeexdsp -lcurl -lzip -lrtaudio -lrtmidi | |||
-Ldep/lib -lGLEW -lglfw -ljansson -lspeexdsp -lcurl -lzip -lrtaudio -lrtmidi -lcrypto -lssl | |||
TARGET = Rack | |||
BUNDLE = dist/$(TARGET).app | |||
endif | |||
@@ -33,7 +33,7 @@ ifeq ($(ARCH), win) | |||
LDFLAGS += -static-libgcc -static-libstdc++ -lpthread \ | |||
-Wl,--export-all-symbols,--out-implib,libRack.a -mwindows \ | |||
-lgdi32 -lopengl32 -lcomdlg32 -lole32 \ | |||
-Ldep/lib -lglew32 -lglfw3dll -lcurl -lzip -lrtaudio -lrtmidi \ | |||
-Ldep/lib -lglew32 -lglfw3dll -lcurl -lzip -lrtaudio -lrtmidi -lcrypto -lssl \ | |||
-Wl,-Bstatic -ljansson -lspeexdsp | |||
TARGET = Rack.exe | |||
OBJECTS = Rack.res | |||
@@ -112,8 +112,14 @@ ifeq ($(ARCH), mac) | |||
cp dep/lib/libspeexdsp.1.dylib $(BUNDLE)/Contents/MacOS/ | |||
cp dep/lib/libcurl.4.dylib $(BUNDLE)/Contents/MacOS/ | |||
cp dep/lib/libzip.5.dylib $(BUNDLE)/Contents/MacOS/ | |||
<<<<<<< HEAD | |||
cp dep/lib/librtmidi.4.dylib $(BUNDLE)/Contents/MacOS/ | |||
cp dep/lib/librtaudio.dylib $(BUNDLE)/Contents/MacOS/ | |||
======= | |||
cp dep/lib/librtaudio.dylib $(BUNDLE)/Contents/MacOS/ | |||
cp dep/lib/librtmidi.4.dylib $(BUNDLE)/Contents/MacOS/ | |||
cp dep/lib/libcrypto.1.1.dylib $(BUNDLE)/Contents/MacOS/ | |||
>>>>>>> v0.5 | |||
install_name_tool -change /usr/local/lib/libGLEW.2.1.0.dylib @executable_path/libGLEW.2.1.0.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
install_name_tool -change lib/libglfw.3.dylib @executable_path/libglfw.3.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
@@ -121,8 +127,14 @@ ifeq ($(ARCH), mac) | |||
install_name_tool -change $(PWD)/dep/lib/libspeexdsp.1.dylib @executable_path/libspeexdsp.1.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
install_name_tool -change $(PWD)/dep/lib/libcurl.4.dylib @executable_path/libcurl.4.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
install_name_tool -change $(PWD)/dep/lib/libzip.5.dylib @executable_path/libzip.5.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
<<<<<<< HEAD | |||
install_name_tool -change $(PWD)/dep/lib/librtmidi.4.dylib @executable_path/librtmidi.4.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
install_name_tool -change librtaudio.dylib @executable_path/librtaudio.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
======= | |||
install_name_tool -change librtaudio.dylib @executable_path/librtaudio.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
install_name_tool -change $(PWD)/dep/lib/librtmidi.4.dylib @executable_path/librtmidi.4.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
install_name_tool -change $(PWD)/dep/lib/libcrypto.1.1.dylib @executable_path/libcrypto.1.1.dylib $(BUNDLE)/Contents/MacOS/Rack | |||
>>>>>>> v0.5 | |||
otool -L $(BUNDLE)/Contents/MacOS/Rack | |||
@@ -149,6 +161,8 @@ ifeq ($(ARCH), win) | |||
cp dep/bin/libspeexdsp-1.dll dist/Rack/ | |||
cp dep/bin/libzip-5.dll dist/Rack/ | |||
cp dep/bin/librtaudio.dll dist/Rack/ | |||
cp dep/bin/libcrypto-1_1-x64.dll dist/Rack/ | |||
cp dep/bin/libssl-1_1-x64.dll dist/Rack/ | |||
mkdir -p dist/Rack/plugins | |||
cp -R plugins/Fundamental/dist/Fundamental dist/Rack/plugins/ | |||
# Make ZIP | |||
@@ -169,6 +183,8 @@ ifeq ($(ARCH), lin) | |||
cp dep/lib/libzip.so.5 dist/Rack/ | |||
cp dep/lib/librtaudio.so dist/Rack/ | |||
cp dep/lib/librtmidi.so.4 dist/Rack/ | |||
cp dep/lib/libssl.so.1.1 dist/Rack/ | |||
cp dep/lib/libcrypto.so.1.1 dist/Rack/ | |||
mkdir -p dist/Rack/plugins | |||
cp -R plugins/Fundamental/dist/Fundamental dist/Rack/plugins/ | |||
# Make ZIP | |||
@@ -31,6 +31,7 @@ ifeq ($(ARCH),lin) | |||
libzip = lib/libzip.so | |||
rtmidi = lib/librtmidi.so | |||
rtaudio = lib/librtaudio.so | |||
openssl = lib/libssl.so | |||
endif | |||
ifeq ($(ARCH),mac) | |||
@@ -42,6 +43,7 @@ ifeq ($(ARCH),mac) | |||
libzip = lib/libzip.dylib | |||
rtmidi = lib/librtmidi.dylib | |||
rtaudio = lib/librtaudio.dylib | |||
openssl = lib/libssl.dylib | |||
endif | |||
ifeq ($(ARCH),win) | |||
@@ -52,7 +54,8 @@ ifeq ($(ARCH),win) | |||
libcurl = bin/libcurl-4.dll | |||
libzip = bin/libzip-5.dll | |||
rtmidi = bin/librtmidi-4.dll | |||
rtaudio = bin/librtaudio-6.dll | |||
rtaudio = bin/librtaudio.dll | |||
openssl = bin/libssl-1_1-x64.dll | |||
endif | |||
# Library configuration | |||
@@ -106,12 +109,20 @@ $(libspeexdsp): | |||
$(MAKE) -C speexdsp-SpeexDSP-1.2rc3 | |||
$(MAKE) -C speexdsp-SpeexDSP-1.2rc3 install | |||
$(libcurl): | |||
$(openssl): | |||
$(WGET) https://www.openssl.org/source/openssl-1.1.0g.tar.gz | |||
$(UNTAR) openssl-1.1.0g.tar.gz | |||
cd openssl-1.1.0g && ./config --prefix="$(LOCAL)" | |||
$(MAKE) -C openssl-1.1.0g | |||
$(MAKE) -C openssl-1.1.0g install | |||
$(libcurl): $(openssl) | |||
$(WGET) https://github.com/curl/curl/releases/download/curl-7_56_0/curl-7.56.0.tar.gz | |||
$(UNTAR) curl-7.56.0.tar.gz | |||
cd curl-7.56.0 && ./configure --prefix="$(LOCAL)" \ | |||
--disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp --disable-proxy --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb --disable-smtp --disable-gopher --disable-manual \ | |||
--without-zlib --without-ssl --without-ca-bundle --without-ca-path --without-ca-fallback --without-libpsl --without-libmetalink --without-libssh2 --without-librtmp --without-winidn --without-libidn2 --without-nghttp2 | |||
--without-zlib --without-libpsl --without-libmetalink --without-libssh2 --without-librtmp --without-winidn --without-libidn2 --without-nghttp2 \ | |||
--without-ca-bundle --with-ca-fallback --with-ssl="$(LOCAL)" | |||
$(MAKE) -C curl-7.56.0 | |||
$(MAKE) -C curl-7.56.0 install | |||
@@ -461,6 +461,14 @@ struct CKSS : SVGSwitch, ToggleSwitch { | |||
} | |||
}; | |||
struct CKSSThree : SVGSwitch, ToggleSwitch { | |||
CKSSThree() { | |||
addFrame(SVG::load(assetGlobal("res/ComponentLibrary/CKSSThree_0.svg"))); | |||
addFrame(SVG::load(assetGlobal("res/ComponentLibrary/CKSSThree_1.svg"))); | |||
addFrame(SVG::load(assetGlobal("res/ComponentLibrary/CKSSThree_2.svg"))); | |||
} | |||
}; | |||
struct CKD6 : SVGSwitch, MomentarySwitch { | |||
CKD6() { | |||
addFrame(SVG::load(assetGlobal("res/ComponentLibrary/CKD6_0.svg"))); | |||
@@ -60,7 +60,8 @@ void pluginInit(); | |||
void pluginDestroy(); | |||
void pluginLogIn(std::string email, std::string password); | |||
void pluginLogOut(); | |||
void pluginRefresh(); | |||
/** Returns whether a new plugin is available, and downloads it unless doing a dry run */ | |||
bool pluginSync(bool dryRun); | |||
void pluginCancelDownload(); | |||
bool pluginIsLoggedIn(); | |||
bool pluginIsDownloading(); | |||
@@ -30,6 +30,16 @@ will expand to | |||
#define LENGTHOF(arr) (sizeof(arr) / sizeof((arr)[0])) | |||
/** Reserve space for _count enums starting with _name. | |||
Example: | |||
enum Foo { | |||
ENUMS(BAR, 14) | |||
}; | |||
BAR + 0 to BAR + 11 is reserved | |||
*/ | |||
#define ENUMS(_name, _count) _name, _name ## _LAST = _name + (_count) - 1 | |||
/** Deprecation notice for GCC */ | |||
#define DEPRECATED __attribute__ ((deprecated)) | |||
@@ -19,5 +19,6 @@ json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ); | |||
/** Returns the filename, blank if unsuccessful */ | |||
bool requestDownload(std::string url, std::string filename, float *progress); | |||
std::string requestEscape(std::string s); | |||
std::string requestSHA256File(std::string filename); | |||
} // namespace rack |
@@ -0,0 +1,321 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
width="4.7473302mm" | |||
height="10.000424mm" | |||
viewBox="0 0 4.7473302 10.000424" | |||
version="1.1" | |||
id="svg258108" | |||
inkscape:version="0.92.2 5c3e80d, 2017-08-06" | |||
sodipodi:docname="CKSSThree_0.svg"> | |||
<defs | |||
id="defs258102"> | |||
<linearGradient | |||
id="linear20" | |||
gradientUnits="userSpaceOnUse" | |||
x1="-0.095554203" | |||
y1="0" | |||
x2="1.32507" | |||
y2="0" | |||
gradientTransform="matrix(0,6.4087959,-6.4087959,0,102.632,66.415358)"> | |||
<stop | |||
offset="0" | |||
style="stop-color:rgb(25.489807%,25.097656%,25.881958%);stop-opacity:1;" | |||
id="stop217759" /> | |||
<stop | |||
offset="0.0625" | |||
style="stop-color:rgb(25.489807%,25.097656%,25.881958%);stop-opacity:1;" | |||
id="stop217761" /> | |||
<stop | |||
offset="0.078125" | |||
style="stop-color:rgb(25.398254%,24.996948%,25.778198%);stop-opacity:1;" | |||
id="stop217763" /> | |||
<stop | |||
offset="0.09375" | |||
style="stop-color:rgb(25.177002%,24.754333%,25.527954%);stop-opacity:1;" | |||
id="stop217765" /> | |||
<stop | |||
offset="0.109375" | |||
style="stop-color:rgb(24.916077%,24.465942%,25.231934%);stop-opacity:1;" | |||
id="stop217767" /> | |||
<stop | |||
offset="0.125" | |||
style="stop-color:rgb(24.653625%,24.179077%,24.935913%);stop-opacity:1;" | |||
id="stop217769" /> | |||
<stop | |||
offset="0.140625" | |||
style="stop-color:rgb(24.3927%,23.892212%,24.639893%);stop-opacity:1;" | |||
id="stop217771" /> | |||
<stop | |||
offset="0.15625" | |||
style="stop-color:rgb(24.131775%,23.605347%,24.343872%);stop-opacity:1;" | |||
id="stop217773" /> | |||
<stop | |||
offset="0.171875" | |||
style="stop-color:rgb(23.87085%,23.316956%,24.047852%);stop-opacity:1;" | |||
id="stop217775" /> | |||
<stop | |||
offset="0.1875" | |||
style="stop-color:rgb(23.609924%,23.03009%,23.751831%);stop-opacity:1;" | |||
id="stop217777" /> | |||
<stop | |||
offset="0.203125" | |||
style="stop-color:rgb(23.348999%,22.743225%,23.455811%);stop-opacity:1;" | |||
id="stop217779" /> | |||
<stop | |||
offset="0.21875" | |||
style="stop-color:rgb(23.088074%,22.45636%,23.15979%);stop-opacity:1;" | |||
id="stop217781" /> | |||
<stop | |||
offset="0.234375" | |||
style="stop-color:rgb(22.825623%,22.167969%,22.86377%);stop-opacity:1;" | |||
id="stop217783" /> | |||
<stop | |||
offset="0.25" | |||
style="stop-color:rgb(22.564697%,21.881104%,22.567749%);stop-opacity:1;" | |||
id="stop217785" /> | |||
<stop | |||
offset="0.265625" | |||
style="stop-color:rgb(22.303772%,21.594238%,22.271729%);stop-opacity:1;" | |||
id="stop217787" /> | |||
<stop | |||
offset="0.28125" | |||
style="stop-color:rgb(22.042847%,21.307373%,21.975708%);stop-opacity:1;" | |||
id="stop217789" /> | |||
<stop | |||
offset="0.296875" | |||
style="stop-color:rgb(21.781921%,21.018982%,21.679688%);stop-opacity:1;" | |||
id="stop217791" /> | |||
<stop | |||
offset="0.3125" | |||
style="stop-color:rgb(21.520996%,20.732117%,21.383667%);stop-opacity:1;" | |||
id="stop217793" /> | |||
<stop | |||
offset="0.328125" | |||
style="stop-color:rgb(21.260071%,20.445251%,21.087646%);stop-opacity:1;" | |||
id="stop217795" /> | |||
<stop | |||
offset="0.34375" | |||
style="stop-color:rgb(20.99762%,20.15686%,20.793152%);stop-opacity:1;" | |||
id="stop217797" /> | |||
<stop | |||
offset="0.359375" | |||
style="stop-color:rgb(20.736694%,19.869995%,20.497131%);stop-opacity:1;" | |||
id="stop217799" /> | |||
<stop | |||
offset="0.375" | |||
style="stop-color:rgb(20.475769%,19.58313%,20.201111%);stop-opacity:1;" | |||
id="stop217801" /> | |||
<stop | |||
offset="0.390625" | |||
style="stop-color:rgb(20.214844%,19.296265%,19.90509%);stop-opacity:1;" | |||
id="stop217803" /> | |||
<stop | |||
offset="0.40625" | |||
style="stop-color:rgb(19.953918%,19.007874%,19.60907%);stop-opacity:1;" | |||
id="stop217805" /> | |||
<stop | |||
offset="0.421875" | |||
style="stop-color:rgb(19.692993%,18.721008%,19.313049%);stop-opacity:1;" | |||
id="stop217807" /> | |||
<stop | |||
offset="0.4375" | |||
style="stop-color:rgb(19.432068%,18.434143%,19.017029%);stop-opacity:1;" | |||
id="stop217809" /> | |||
<stop | |||
offset="0.453125" | |||
style="stop-color:rgb(19.169617%,18.147278%,18.721008%);stop-opacity:1;" | |||
id="stop217811" /> | |||
<stop | |||
offset="0.46875" | |||
style="stop-color:rgb(18.908691%,17.858887%,18.424988%);stop-opacity:1;" | |||
id="stop217813" /> | |||
<stop | |||
offset="0.484375" | |||
style="stop-color:rgb(18.647766%,17.572021%,18.128967%);stop-opacity:1;" | |||
id="stop217815" /> | |||
<stop | |||
offset="0.5" | |||
style="stop-color:rgb(18.386841%,17.285156%,17.832947%);stop-opacity:1;" | |||
id="stop217817" /> | |||
<stop | |||
offset="0.515625" | |||
style="stop-color:rgb(18.125916%,16.998291%,17.536926%);stop-opacity:1;" | |||
id="stop217819" /> | |||
<stop | |||
offset="0.53125" | |||
style="stop-color:rgb(17.86499%,16.7099%,17.240906%);stop-opacity:1;" | |||
id="stop217821" /> | |||
<stop | |||
offset="0.546875" | |||
style="stop-color:rgb(17.604065%,16.423035%,16.944885%);stop-opacity:1;" | |||
id="stop217823" /> | |||
<stop | |||
offset="0.5625" | |||
style="stop-color:rgb(17.341614%,16.136169%,16.648865%);stop-opacity:1;" | |||
id="stop217825" /> | |||
<stop | |||
offset="0.578125" | |||
style="stop-color:rgb(17.080688%,15.849304%,16.352844%);stop-opacity:1;" | |||
id="stop217827" /> | |||
<stop | |||
offset="0.59375" | |||
style="stop-color:rgb(16.819763%,15.560913%,16.056824%);stop-opacity:1;" | |||
id="stop217829" /> | |||
<stop | |||
offset="0.609375" | |||
style="stop-color:rgb(16.558838%,15.274048%,15.760803%);stop-opacity:1;" | |||
id="stop217831" /> | |||
<stop | |||
offset="0.625" | |||
style="stop-color:rgb(16.297913%,14.987183%,15.464783%);stop-opacity:1;" | |||
id="stop217833" /> | |||
<stop | |||
offset="0.640625" | |||
style="stop-color:rgb(16.036987%,14.700317%,15.168762%);stop-opacity:1;" | |||
id="stop217835" /> | |||
<stop | |||
offset="0.65625" | |||
style="stop-color:rgb(15.776062%,14.411926%,14.872742%);stop-opacity:1;" | |||
id="stop217837" /> | |||
<stop | |||
offset="0.671875" | |||
style="stop-color:rgb(15.513611%,14.125061%,14.576721%);stop-opacity:1;" | |||
id="stop217839" /> | |||
<stop | |||
offset="0.6875" | |||
style="stop-color:rgb(15.252686%,13.838196%,14.280701%);stop-opacity:1;" | |||
id="stop217841" /> | |||
<stop | |||
offset="0.703125" | |||
style="stop-color:rgb(14.99176%,13.551331%,13.98468%);stop-opacity:1;" | |||
id="stop217843" /> | |||
<stop | |||
offset="0.71875" | |||
style="stop-color:rgb(14.730835%,13.262939%,13.68866%);stop-opacity:1;" | |||
id="stop217845" /> | |||
<stop | |||
offset="0.734375" | |||
style="stop-color:rgb(14.46991%,12.976074%,13.392639%);stop-opacity:1;" | |||
id="stop217847" /> | |||
<stop | |||
offset="0.75" | |||
style="stop-color:rgb(14.208984%,12.689209%,13.096619%);stop-opacity:1;" | |||
id="stop217849" /> | |||
<stop | |||
offset="0.765625" | |||
style="stop-color:rgb(13.948059%,12.402344%,12.802124%);stop-opacity:1;" | |||
id="stop217851" /> | |||
<stop | |||
offset="0.78125" | |||
style="stop-color:rgb(13.771057%,12.207031%,12.600708%);stop-opacity:1;" | |||
id="stop217853" /> | |||
<stop | |||
offset="0.8125" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217855" /> | |||
<stop | |||
offset="0.875" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217857" /> | |||
<stop | |||
offset="1" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217859" /> | |||
</linearGradient> | |||
</defs> | |||
<sodipodi:namedview | |||
id="base" | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1.0" | |||
inkscape:pageopacity="0.0" | |||
inkscape:pageshadow="2" | |||
inkscape:zoom="11.2" | |||
inkscape:cx="10.029443" | |||
inkscape:cy="16.956782" | |||
inkscape:document-units="mm" | |||
inkscape:current-layer="g258244" | |||
showgrid="false" | |||
fit-margin-top="0" | |||
fit-margin-left="0" | |||
fit-margin-right="0" | |||
fit-margin-bottom="0" | |||
inkscape:window-width="1600" | |||
inkscape:window-height="882" | |||
inkscape:window-x="0" | |||
inkscape:window-y="18" | |||
inkscape:window-maximized="0" /> | |||
<metadata | |||
id="metadata258105"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
<dc:title></dc:title> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<g | |||
inkscape:label="Layer 1" | |||
inkscape:groupmode="layer" | |||
id="layer1" | |||
transform="translate(-100.25783,-65.355229)"> | |||
<g | |||
id="g258244"> | |||
<path | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.25783,65.855457 c 0,-0.275608 0.22599,-0.500228 0.50021,-0.500228 h 3.74826 c 0.27425,0 0.49886,0.22462 0.49886,0.500228 v 8.999967 c 0,0.274229 -0.22461,0.500229 -0.49886,0.500229 h -3.74826 c -0.27422,0 -0.50021,-0.226 -0.50021,-0.500229 z m 0,0" | |||
id="path243332" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="clip-rule:nonzero;fill:#414042;fill-rule:nonzero;stroke:none;stroke-width:0.35277775;fill-opacity:1" | |||
d="m 104.56144,65.803091 h -3.85851 v 9.1047 h 3.85851 z m 0,0" | |||
id="path243334" | |||
inkscape:connector-curvature="0" /> | |||
</g> | |||
<g | |||
id="g258240"> | |||
<path | |||
style="fill:#424242;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,71.907801 h 3.85988 v 2.99999 h -3.85988 z m 0,0" | |||
id="path243340" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,73.241742 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243342" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,74.577062 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243344" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,73.91009 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243346" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,72.574773 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243348" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,71.907801 h 3.85988 v 0.329349 h -3.85988 z m 0,0" | |||
id="path243350" | |||
inkscape:connector-curvature="0" /> | |||
</g> | |||
</g> | |||
</svg> |
@@ -0,0 +1,322 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
width="4.7473302mm" | |||
height="10.000424mm" | |||
viewBox="0 0 4.7473302 10.000424" | |||
version="1.1" | |||
id="svg258108" | |||
inkscape:version="0.92.2 5c3e80d, 2017-08-06" | |||
sodipodi:docname="CKSSThree_1.svg"> | |||
<defs | |||
id="defs258102"> | |||
<linearGradient | |||
id="linear20" | |||
gradientUnits="userSpaceOnUse" | |||
x1="-0.095554203" | |||
y1="0" | |||
x2="1.32507" | |||
y2="0" | |||
gradientTransform="matrix(0,6.4087959,-6.4087959,0,102.632,66.415358)"> | |||
<stop | |||
offset="0" | |||
style="stop-color:rgb(25.489807%,25.097656%,25.881958%);stop-opacity:1;" | |||
id="stop217759" /> | |||
<stop | |||
offset="0.0625" | |||
style="stop-color:rgb(25.489807%,25.097656%,25.881958%);stop-opacity:1;" | |||
id="stop217761" /> | |||
<stop | |||
offset="0.078125" | |||
style="stop-color:rgb(25.398254%,24.996948%,25.778198%);stop-opacity:1;" | |||
id="stop217763" /> | |||
<stop | |||
offset="0.09375" | |||
style="stop-color:rgb(25.177002%,24.754333%,25.527954%);stop-opacity:1;" | |||
id="stop217765" /> | |||
<stop | |||
offset="0.109375" | |||
style="stop-color:rgb(24.916077%,24.465942%,25.231934%);stop-opacity:1;" | |||
id="stop217767" /> | |||
<stop | |||
offset="0.125" | |||
style="stop-color:rgb(24.653625%,24.179077%,24.935913%);stop-opacity:1;" | |||
id="stop217769" /> | |||
<stop | |||
offset="0.140625" | |||
style="stop-color:rgb(24.3927%,23.892212%,24.639893%);stop-opacity:1;" | |||
id="stop217771" /> | |||
<stop | |||
offset="0.15625" | |||
style="stop-color:rgb(24.131775%,23.605347%,24.343872%);stop-opacity:1;" | |||
id="stop217773" /> | |||
<stop | |||
offset="0.171875" | |||
style="stop-color:rgb(23.87085%,23.316956%,24.047852%);stop-opacity:1;" | |||
id="stop217775" /> | |||
<stop | |||
offset="0.1875" | |||
style="stop-color:rgb(23.609924%,23.03009%,23.751831%);stop-opacity:1;" | |||
id="stop217777" /> | |||
<stop | |||
offset="0.203125" | |||
style="stop-color:rgb(23.348999%,22.743225%,23.455811%);stop-opacity:1;" | |||
id="stop217779" /> | |||
<stop | |||
offset="0.21875" | |||
style="stop-color:rgb(23.088074%,22.45636%,23.15979%);stop-opacity:1;" | |||
id="stop217781" /> | |||
<stop | |||
offset="0.234375" | |||
style="stop-color:rgb(22.825623%,22.167969%,22.86377%);stop-opacity:1;" | |||
id="stop217783" /> | |||
<stop | |||
offset="0.25" | |||
style="stop-color:rgb(22.564697%,21.881104%,22.567749%);stop-opacity:1;" | |||
id="stop217785" /> | |||
<stop | |||
offset="0.265625" | |||
style="stop-color:rgb(22.303772%,21.594238%,22.271729%);stop-opacity:1;" | |||
id="stop217787" /> | |||
<stop | |||
offset="0.28125" | |||
style="stop-color:rgb(22.042847%,21.307373%,21.975708%);stop-opacity:1;" | |||
id="stop217789" /> | |||
<stop | |||
offset="0.296875" | |||
style="stop-color:rgb(21.781921%,21.018982%,21.679688%);stop-opacity:1;" | |||
id="stop217791" /> | |||
<stop | |||
offset="0.3125" | |||
style="stop-color:rgb(21.520996%,20.732117%,21.383667%);stop-opacity:1;" | |||
id="stop217793" /> | |||
<stop | |||
offset="0.328125" | |||
style="stop-color:rgb(21.260071%,20.445251%,21.087646%);stop-opacity:1;" | |||
id="stop217795" /> | |||
<stop | |||
offset="0.34375" | |||
style="stop-color:rgb(20.99762%,20.15686%,20.793152%);stop-opacity:1;" | |||
id="stop217797" /> | |||
<stop | |||
offset="0.359375" | |||
style="stop-color:rgb(20.736694%,19.869995%,20.497131%);stop-opacity:1;" | |||
id="stop217799" /> | |||
<stop | |||
offset="0.375" | |||
style="stop-color:rgb(20.475769%,19.58313%,20.201111%);stop-opacity:1;" | |||
id="stop217801" /> | |||
<stop | |||
offset="0.390625" | |||
style="stop-color:rgb(20.214844%,19.296265%,19.90509%);stop-opacity:1;" | |||
id="stop217803" /> | |||
<stop | |||
offset="0.40625" | |||
style="stop-color:rgb(19.953918%,19.007874%,19.60907%);stop-opacity:1;" | |||
id="stop217805" /> | |||
<stop | |||
offset="0.421875" | |||
style="stop-color:rgb(19.692993%,18.721008%,19.313049%);stop-opacity:1;" | |||
id="stop217807" /> | |||
<stop | |||
offset="0.4375" | |||
style="stop-color:rgb(19.432068%,18.434143%,19.017029%);stop-opacity:1;" | |||
id="stop217809" /> | |||
<stop | |||
offset="0.453125" | |||
style="stop-color:rgb(19.169617%,18.147278%,18.721008%);stop-opacity:1;" | |||
id="stop217811" /> | |||
<stop | |||
offset="0.46875" | |||
style="stop-color:rgb(18.908691%,17.858887%,18.424988%);stop-opacity:1;" | |||
id="stop217813" /> | |||
<stop | |||
offset="0.484375" | |||
style="stop-color:rgb(18.647766%,17.572021%,18.128967%);stop-opacity:1;" | |||
id="stop217815" /> | |||
<stop | |||
offset="0.5" | |||
style="stop-color:rgb(18.386841%,17.285156%,17.832947%);stop-opacity:1;" | |||
id="stop217817" /> | |||
<stop | |||
offset="0.515625" | |||
style="stop-color:rgb(18.125916%,16.998291%,17.536926%);stop-opacity:1;" | |||
id="stop217819" /> | |||
<stop | |||
offset="0.53125" | |||
style="stop-color:rgb(17.86499%,16.7099%,17.240906%);stop-opacity:1;" | |||
id="stop217821" /> | |||
<stop | |||
offset="0.546875" | |||
style="stop-color:rgb(17.604065%,16.423035%,16.944885%);stop-opacity:1;" | |||
id="stop217823" /> | |||
<stop | |||
offset="0.5625" | |||
style="stop-color:rgb(17.341614%,16.136169%,16.648865%);stop-opacity:1;" | |||
id="stop217825" /> | |||
<stop | |||
offset="0.578125" | |||
style="stop-color:rgb(17.080688%,15.849304%,16.352844%);stop-opacity:1;" | |||
id="stop217827" /> | |||
<stop | |||
offset="0.59375" | |||
style="stop-color:rgb(16.819763%,15.560913%,16.056824%);stop-opacity:1;" | |||
id="stop217829" /> | |||
<stop | |||
offset="0.609375" | |||
style="stop-color:rgb(16.558838%,15.274048%,15.760803%);stop-opacity:1;" | |||
id="stop217831" /> | |||
<stop | |||
offset="0.625" | |||
style="stop-color:rgb(16.297913%,14.987183%,15.464783%);stop-opacity:1;" | |||
id="stop217833" /> | |||
<stop | |||
offset="0.640625" | |||
style="stop-color:rgb(16.036987%,14.700317%,15.168762%);stop-opacity:1;" | |||
id="stop217835" /> | |||
<stop | |||
offset="0.65625" | |||
style="stop-color:rgb(15.776062%,14.411926%,14.872742%);stop-opacity:1;" | |||
id="stop217837" /> | |||
<stop | |||
offset="0.671875" | |||
style="stop-color:rgb(15.513611%,14.125061%,14.576721%);stop-opacity:1;" | |||
id="stop217839" /> | |||
<stop | |||
offset="0.6875" | |||
style="stop-color:rgb(15.252686%,13.838196%,14.280701%);stop-opacity:1;" | |||
id="stop217841" /> | |||
<stop | |||
offset="0.703125" | |||
style="stop-color:rgb(14.99176%,13.551331%,13.98468%);stop-opacity:1;" | |||
id="stop217843" /> | |||
<stop | |||
offset="0.71875" | |||
style="stop-color:rgb(14.730835%,13.262939%,13.68866%);stop-opacity:1;" | |||
id="stop217845" /> | |||
<stop | |||
offset="0.734375" | |||
style="stop-color:rgb(14.46991%,12.976074%,13.392639%);stop-opacity:1;" | |||
id="stop217847" /> | |||
<stop | |||
offset="0.75" | |||
style="stop-color:rgb(14.208984%,12.689209%,13.096619%);stop-opacity:1;" | |||
id="stop217849" /> | |||
<stop | |||
offset="0.765625" | |||
style="stop-color:rgb(13.948059%,12.402344%,12.802124%);stop-opacity:1;" | |||
id="stop217851" /> | |||
<stop | |||
offset="0.78125" | |||
style="stop-color:rgb(13.771057%,12.207031%,12.600708%);stop-opacity:1;" | |||
id="stop217853" /> | |||
<stop | |||
offset="0.8125" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217855" /> | |||
<stop | |||
offset="0.875" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217857" /> | |||
<stop | |||
offset="1" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217859" /> | |||
</linearGradient> | |||
</defs> | |||
<sodipodi:namedview | |||
id="base" | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1.0" | |||
inkscape:pageopacity="0.0" | |||
inkscape:pageshadow="2" | |||
inkscape:zoom="11.2" | |||
inkscape:cx="10.922301" | |||
inkscape:cy="16.956782" | |||
inkscape:document-units="mm" | |||
inkscape:current-layer="layer1" | |||
showgrid="false" | |||
fit-margin-top="0" | |||
fit-margin-left="0" | |||
fit-margin-right="0" | |||
fit-margin-bottom="0" | |||
inkscape:window-width="1600" | |||
inkscape:window-height="882" | |||
inkscape:window-x="0" | |||
inkscape:window-y="18" | |||
inkscape:window-maximized="0" /> | |||
<metadata | |||
id="metadata258105"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
<dc:title></dc:title> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<g | |||
inkscape:label="Layer 1" | |||
inkscape:groupmode="layer" | |||
id="layer1" | |||
transform="translate(-100.25783,-65.355229)"> | |||
<g | |||
id="g258244"> | |||
<path | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.25783,65.855457 c 0,-0.275608 0.22599,-0.500228 0.50021,-0.500228 h 3.74826 c 0.27425,0 0.49886,0.22462 0.49886,0.500228 v 8.999967 c 0,0.274229 -0.22461,0.500229 -0.49886,0.500229 h -3.74826 c -0.27422,0 -0.50021,-0.226 -0.50021,-0.500229 z m 0,0" | |||
id="path243332" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="clip-rule:nonzero;fill:#414042;fill-rule:nonzero;stroke:none;stroke-width:0.35277775;fill-opacity:1" | |||
d="m 104.56144,65.803091 h -3.85851 v 9.1047 h 3.85851 z m 0,0" | |||
id="path243334" | |||
inkscape:connector-curvature="0" /> | |||
</g> | |||
<g | |||
id="g258240" | |||
transform="translate(0,-3.0523548)"> | |||
<path | |||
style="fill:#424242;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,71.907801 h 3.85988 v 2.99999 h -3.85988 z m 0,0" | |||
id="path243340" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,73.241742 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243342" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,74.577062 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243344" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,73.91009 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243346" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,72.574773 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243348" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,71.907801 h 3.85988 v 0.329349 h -3.85988 z m 0,0" | |||
id="path243350" | |||
inkscape:connector-curvature="0" /> | |||
</g> | |||
</g> | |||
</svg> |
@@ -0,0 +1,322 @@ | |||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |||
<!-- Created with Inkscape (http://www.inkscape.org/) --> | |||
<svg | |||
xmlns:dc="http://purl.org/dc/elements/1.1/" | |||
xmlns:cc="http://creativecommons.org/ns#" | |||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |||
xmlns:svg="http://www.w3.org/2000/svg" | |||
xmlns="http://www.w3.org/2000/svg" | |||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |||
width="4.7473302mm" | |||
height="10.000424mm" | |||
viewBox="0 0 4.7473302 10.000424" | |||
version="1.1" | |||
id="svg258108" | |||
inkscape:version="0.92.2 5c3e80d, 2017-08-06" | |||
sodipodi:docname="CKSSThree_2.svg"> | |||
<defs | |||
id="defs258102"> | |||
<linearGradient | |||
id="linear20" | |||
gradientUnits="userSpaceOnUse" | |||
x1="-0.095554203" | |||
y1="0" | |||
x2="1.32507" | |||
y2="0" | |||
gradientTransform="matrix(0,6.4087959,-6.4087959,0,102.632,66.415358)"> | |||
<stop | |||
offset="0" | |||
style="stop-color:rgb(25.489807%,25.097656%,25.881958%);stop-opacity:1;" | |||
id="stop217759" /> | |||
<stop | |||
offset="0.0625" | |||
style="stop-color:rgb(25.489807%,25.097656%,25.881958%);stop-opacity:1;" | |||
id="stop217761" /> | |||
<stop | |||
offset="0.078125" | |||
style="stop-color:rgb(25.398254%,24.996948%,25.778198%);stop-opacity:1;" | |||
id="stop217763" /> | |||
<stop | |||
offset="0.09375" | |||
style="stop-color:rgb(25.177002%,24.754333%,25.527954%);stop-opacity:1;" | |||
id="stop217765" /> | |||
<stop | |||
offset="0.109375" | |||
style="stop-color:rgb(24.916077%,24.465942%,25.231934%);stop-opacity:1;" | |||
id="stop217767" /> | |||
<stop | |||
offset="0.125" | |||
style="stop-color:rgb(24.653625%,24.179077%,24.935913%);stop-opacity:1;" | |||
id="stop217769" /> | |||
<stop | |||
offset="0.140625" | |||
style="stop-color:rgb(24.3927%,23.892212%,24.639893%);stop-opacity:1;" | |||
id="stop217771" /> | |||
<stop | |||
offset="0.15625" | |||
style="stop-color:rgb(24.131775%,23.605347%,24.343872%);stop-opacity:1;" | |||
id="stop217773" /> | |||
<stop | |||
offset="0.171875" | |||
style="stop-color:rgb(23.87085%,23.316956%,24.047852%);stop-opacity:1;" | |||
id="stop217775" /> | |||
<stop | |||
offset="0.1875" | |||
style="stop-color:rgb(23.609924%,23.03009%,23.751831%);stop-opacity:1;" | |||
id="stop217777" /> | |||
<stop | |||
offset="0.203125" | |||
style="stop-color:rgb(23.348999%,22.743225%,23.455811%);stop-opacity:1;" | |||
id="stop217779" /> | |||
<stop | |||
offset="0.21875" | |||
style="stop-color:rgb(23.088074%,22.45636%,23.15979%);stop-opacity:1;" | |||
id="stop217781" /> | |||
<stop | |||
offset="0.234375" | |||
style="stop-color:rgb(22.825623%,22.167969%,22.86377%);stop-opacity:1;" | |||
id="stop217783" /> | |||
<stop | |||
offset="0.25" | |||
style="stop-color:rgb(22.564697%,21.881104%,22.567749%);stop-opacity:1;" | |||
id="stop217785" /> | |||
<stop | |||
offset="0.265625" | |||
style="stop-color:rgb(22.303772%,21.594238%,22.271729%);stop-opacity:1;" | |||
id="stop217787" /> | |||
<stop | |||
offset="0.28125" | |||
style="stop-color:rgb(22.042847%,21.307373%,21.975708%);stop-opacity:1;" | |||
id="stop217789" /> | |||
<stop | |||
offset="0.296875" | |||
style="stop-color:rgb(21.781921%,21.018982%,21.679688%);stop-opacity:1;" | |||
id="stop217791" /> | |||
<stop | |||
offset="0.3125" | |||
style="stop-color:rgb(21.520996%,20.732117%,21.383667%);stop-opacity:1;" | |||
id="stop217793" /> | |||
<stop | |||
offset="0.328125" | |||
style="stop-color:rgb(21.260071%,20.445251%,21.087646%);stop-opacity:1;" | |||
id="stop217795" /> | |||
<stop | |||
offset="0.34375" | |||
style="stop-color:rgb(20.99762%,20.15686%,20.793152%);stop-opacity:1;" | |||
id="stop217797" /> | |||
<stop | |||
offset="0.359375" | |||
style="stop-color:rgb(20.736694%,19.869995%,20.497131%);stop-opacity:1;" | |||
id="stop217799" /> | |||
<stop | |||
offset="0.375" | |||
style="stop-color:rgb(20.475769%,19.58313%,20.201111%);stop-opacity:1;" | |||
id="stop217801" /> | |||
<stop | |||
offset="0.390625" | |||
style="stop-color:rgb(20.214844%,19.296265%,19.90509%);stop-opacity:1;" | |||
id="stop217803" /> | |||
<stop | |||
offset="0.40625" | |||
style="stop-color:rgb(19.953918%,19.007874%,19.60907%);stop-opacity:1;" | |||
id="stop217805" /> | |||
<stop | |||
offset="0.421875" | |||
style="stop-color:rgb(19.692993%,18.721008%,19.313049%);stop-opacity:1;" | |||
id="stop217807" /> | |||
<stop | |||
offset="0.4375" | |||
style="stop-color:rgb(19.432068%,18.434143%,19.017029%);stop-opacity:1;" | |||
id="stop217809" /> | |||
<stop | |||
offset="0.453125" | |||
style="stop-color:rgb(19.169617%,18.147278%,18.721008%);stop-opacity:1;" | |||
id="stop217811" /> | |||
<stop | |||
offset="0.46875" | |||
style="stop-color:rgb(18.908691%,17.858887%,18.424988%);stop-opacity:1;" | |||
id="stop217813" /> | |||
<stop | |||
offset="0.484375" | |||
style="stop-color:rgb(18.647766%,17.572021%,18.128967%);stop-opacity:1;" | |||
id="stop217815" /> | |||
<stop | |||
offset="0.5" | |||
style="stop-color:rgb(18.386841%,17.285156%,17.832947%);stop-opacity:1;" | |||
id="stop217817" /> | |||
<stop | |||
offset="0.515625" | |||
style="stop-color:rgb(18.125916%,16.998291%,17.536926%);stop-opacity:1;" | |||
id="stop217819" /> | |||
<stop | |||
offset="0.53125" | |||
style="stop-color:rgb(17.86499%,16.7099%,17.240906%);stop-opacity:1;" | |||
id="stop217821" /> | |||
<stop | |||
offset="0.546875" | |||
style="stop-color:rgb(17.604065%,16.423035%,16.944885%);stop-opacity:1;" | |||
id="stop217823" /> | |||
<stop | |||
offset="0.5625" | |||
style="stop-color:rgb(17.341614%,16.136169%,16.648865%);stop-opacity:1;" | |||
id="stop217825" /> | |||
<stop | |||
offset="0.578125" | |||
style="stop-color:rgb(17.080688%,15.849304%,16.352844%);stop-opacity:1;" | |||
id="stop217827" /> | |||
<stop | |||
offset="0.59375" | |||
style="stop-color:rgb(16.819763%,15.560913%,16.056824%);stop-opacity:1;" | |||
id="stop217829" /> | |||
<stop | |||
offset="0.609375" | |||
style="stop-color:rgb(16.558838%,15.274048%,15.760803%);stop-opacity:1;" | |||
id="stop217831" /> | |||
<stop | |||
offset="0.625" | |||
style="stop-color:rgb(16.297913%,14.987183%,15.464783%);stop-opacity:1;" | |||
id="stop217833" /> | |||
<stop | |||
offset="0.640625" | |||
style="stop-color:rgb(16.036987%,14.700317%,15.168762%);stop-opacity:1;" | |||
id="stop217835" /> | |||
<stop | |||
offset="0.65625" | |||
style="stop-color:rgb(15.776062%,14.411926%,14.872742%);stop-opacity:1;" | |||
id="stop217837" /> | |||
<stop | |||
offset="0.671875" | |||
style="stop-color:rgb(15.513611%,14.125061%,14.576721%);stop-opacity:1;" | |||
id="stop217839" /> | |||
<stop | |||
offset="0.6875" | |||
style="stop-color:rgb(15.252686%,13.838196%,14.280701%);stop-opacity:1;" | |||
id="stop217841" /> | |||
<stop | |||
offset="0.703125" | |||
style="stop-color:rgb(14.99176%,13.551331%,13.98468%);stop-opacity:1;" | |||
id="stop217843" /> | |||
<stop | |||
offset="0.71875" | |||
style="stop-color:rgb(14.730835%,13.262939%,13.68866%);stop-opacity:1;" | |||
id="stop217845" /> | |||
<stop | |||
offset="0.734375" | |||
style="stop-color:rgb(14.46991%,12.976074%,13.392639%);stop-opacity:1;" | |||
id="stop217847" /> | |||
<stop | |||
offset="0.75" | |||
style="stop-color:rgb(14.208984%,12.689209%,13.096619%);stop-opacity:1;" | |||
id="stop217849" /> | |||
<stop | |||
offset="0.765625" | |||
style="stop-color:rgb(13.948059%,12.402344%,12.802124%);stop-opacity:1;" | |||
id="stop217851" /> | |||
<stop | |||
offset="0.78125" | |||
style="stop-color:rgb(13.771057%,12.207031%,12.600708%);stop-opacity:1;" | |||
id="stop217853" /> | |||
<stop | |||
offset="0.8125" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217855" /> | |||
<stop | |||
offset="0.875" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217857" /> | |||
<stop | |||
offset="1" | |||
style="stop-color:rgb(13.725281%,12.156677%,12.548828%);stop-opacity:1;" | |||
id="stop217859" /> | |||
</linearGradient> | |||
</defs> | |||
<sodipodi:namedview | |||
id="base" | |||
pagecolor="#ffffff" | |||
bordercolor="#666666" | |||
borderopacity="1.0" | |||
inkscape:pageopacity="0.0" | |||
inkscape:pageshadow="2" | |||
inkscape:zoom="11.2" | |||
inkscape:cx="10.922301" | |||
inkscape:cy="16.956782" | |||
inkscape:document-units="mm" | |||
inkscape:current-layer="layer1" | |||
showgrid="false" | |||
fit-margin-top="0" | |||
fit-margin-left="0" | |||
fit-margin-right="0" | |||
fit-margin-bottom="0" | |||
inkscape:window-width="1600" | |||
inkscape:window-height="882" | |||
inkscape:window-x="0" | |||
inkscape:window-y="18" | |||
inkscape:window-maximized="0" /> | |||
<metadata | |||
id="metadata258105"> | |||
<rdf:RDF> | |||
<cc:Work | |||
rdf:about=""> | |||
<dc:format>image/svg+xml</dc:format> | |||
<dc:type | |||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |||
<dc:title></dc:title> | |||
</cc:Work> | |||
</rdf:RDF> | |||
</metadata> | |||
<g | |||
inkscape:label="Layer 1" | |||
inkscape:groupmode="layer" | |||
id="layer1" | |||
transform="translate(-100.25783,-65.355229)"> | |||
<g | |||
id="g258244"> | |||
<path | |||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.25783,65.855457 c 0,-0.275608 0.22599,-0.500228 0.50021,-0.500228 h 3.74826 c 0.27425,0 0.49886,0.22462 0.49886,0.500228 v 8.999967 c 0,0.274229 -0.22461,0.500229 -0.49886,0.500229 h -3.74826 c -0.27422,0 -0.50021,-0.226 -0.50021,-0.500229 z m 0,0" | |||
id="path243332" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="clip-rule:nonzero;fill:#414042;fill-rule:nonzero;stroke:none;stroke-width:0.35277775;fill-opacity:1" | |||
d="m 104.56144,65.803091 h -3.85851 v 9.1047 h 3.85851 z m 0,0" | |||
id="path243334" | |||
inkscape:connector-curvature="0" /> | |||
</g> | |||
<g | |||
id="g258240" | |||
transform="translate(0,-6.10471)"> | |||
<path | |||
style="fill:#424242;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,71.907801 h 3.85988 v 2.99999 h -3.85988 z m 0,0" | |||
id="path243340" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,73.241742 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243342" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,74.577062 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243344" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,73.91009 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243346" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,72.574773 h 3.85988 v 0.330729 h -3.85988 z m 0,0" | |||
id="path243348" | |||
inkscape:connector-curvature="0" /> | |||
<path | |||
style="fill:#979797;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.35277775" | |||
d="m 100.70156,71.907801 h 3.85988 v 0.329349 h -3.85988 z m 0,0" | |||
id="path243350" | |||
inkscape:connector-curvature="0" /> | |||
</g> | |||
</g> | |||
</svg> |
@@ -10,7 +10,8 @@ std::string gApplicationVersion = | |||
#else | |||
""; | |||
#endif | |||
std::string gApiHost = "http://api.vcvrack.com"; | |||
std::string gApiHost = "https://api.vcvrack.com"; | |||
// std::string gApiHost = "http://localhost:8081"; | |||
RackWidget *gRackWidget = NULL; | |||
Toolbar *gToolbar = NULL; | |||
@@ -70,7 +70,7 @@ struct MetadataMenu : ListMenu { | |||
// Plugin metadata | |||
if (!model->plugin->website.empty()) { | |||
addChild(construct<UrlItem>(&MenuEntry::text, "Website", &UrlItem::url, model->plugin->path)); | |||
addChild(construct<UrlItem>(&MenuEntry::text, "Website", &UrlItem::url, model->plugin->website)); | |||
} | |||
if (!model->plugin->manual.empty()) { | |||
addChild(construct<UrlItem>(&MenuEntry::text, "Manual", &UrlItem::url, model->plugin->manual)); | |||
@@ -120,10 +120,6 @@ struct ModelItem : MenuItem { | |||
sModel = model; | |||
MenuItem::onMouseEnter(e); | |||
} | |||
void onMouseLeave(EventMouseLeave &e) override { | |||
sModel = NULL; | |||
MenuItem::onMouseLeave(e); | |||
} | |||
}; | |||
@@ -1,11 +1,57 @@ | |||
#include <thread> | |||
#include "app.hpp" | |||
#include "plugin.hpp" | |||
#include "gui.hpp" | |||
#include "../ext/osdialog/osdialog.h" | |||
namespace rack { | |||
struct SyncButton : Button { | |||
bool checked = false; | |||
bool available = false; | |||
bool completed = false; | |||
void step() override { | |||
if (!checked) { | |||
std::thread t([this]() { | |||
if (pluginSync(true)) | |||
available = true; | |||
}); | |||
t.detach(); | |||
checked = true; | |||
} | |||
if (completed) { | |||
if (osdialog_message(OSDIALOG_INFO, OSDIALOG_OK_CANCEL, "All plugins have been updated. Close Rack and re-launch it to load new updates.")) { | |||
guiClose(); | |||
} | |||
completed = false; | |||
} | |||
} | |||
void draw(NVGcontext *vg) override { | |||
Button::draw(vg); | |||
if (available) { | |||
// Notification circle | |||
nvgBeginPath(vg); | |||
nvgCircle(vg, 3, 3, 4.0); | |||
nvgFillColor(vg, nvgRGBf(1.0, 0.0, 0.0)); | |||
nvgFill(vg); | |||
nvgStrokeColor(vg, nvgRGBf(0.5, 0.0, 0.0)); | |||
nvgStroke(vg); | |||
} | |||
} | |||
void onAction(EventAction &e) override { | |||
available = false; | |||
std::thread t([this]() { | |||
if (pluginSync(false)) | |||
completed = true; | |||
}); | |||
t.detach(); | |||
} | |||
}; | |||
PluginManagerWidget::PluginManagerWidget() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
float margin = 5; | |||
@@ -91,19 +137,13 @@ PluginManagerWidget::PluginManagerWidget() { | |||
manageWidget->addChild(manageButton); | |||
pos.x += manageButton->box.size.x; | |||
struct RefreshButton : Button { | |||
void onAction(EventAction &e) override { | |||
std::thread t(pluginRefresh); | |||
t.detach(); | |||
} | |||
}; | |||
pos.x += margin; | |||
Button *refreshButton = new RefreshButton(); | |||
refreshButton->box.pos = pos; | |||
refreshButton->box.size.x = 125; | |||
refreshButton->text = "Refresh plugins"; | |||
manageWidget->addChild(refreshButton); | |||
pos.x += refreshButton->box.size.x; | |||
Button *syncButton = new SyncButton(); | |||
syncButton->box.pos = pos; | |||
syncButton->box.size.x = 125; | |||
syncButton->text = "Update plugins"; | |||
manageWidget->addChild(syncButton); | |||
pos.x += syncButton->box.size.x; | |||
struct LogOutButton : Button { | |||
void onAction(EventAction &e) override { | |||
@@ -7,11 +7,12 @@ | |||
#include <sys/stat.h> | |||
#include <sys/param.h> // for MAXPATHLEN | |||
#include <fcntl.h> | |||
#include <thread> | |||
#include <zip.h> | |||
#include <jansson.h> | |||
#if ARCH_WIN | |||
#if defined(ARCH_WIN) | |||
#include <windows.h> | |||
#include <direct.h> | |||
#define mkdir(_dir, _perms) _mkdir(_dir) | |||
@@ -189,35 +190,55 @@ static int extractZip(const char *filename, const char *dir) { | |||
return err; | |||
} | |||
static void refreshPurchase(json_t *pluginJ) { | |||
static void syncPlugin(json_t *pluginJ) { | |||
json_t *slugJ = json_object_get(pluginJ, "slug"); | |||
if (!slugJ) return; | |||
std::string slug = json_string_value(slugJ); | |||
info("Syncing plugin %s", slug.c_str()); | |||
json_t *nameJ = json_object_get(pluginJ, "name"); | |||
if (!nameJ) return; | |||
std::string name = json_string_value(nameJ); | |||
json_t *versionJ = json_object_get(pluginJ, "version"); | |||
if (!versionJ) return; | |||
std::string version = json_string_value(versionJ); | |||
// Check whether the plugin is already loaded | |||
for (Plugin *plugin : gPlugins) { | |||
if (plugin->slug == slug && plugin->version == version) { | |||
return; | |||
std::string download; | |||
std::string sha256; | |||
json_t *downloadsJ = json_object_get(pluginJ, "downloads"); | |||
if (downloadsJ) { | |||
#if defined(ARCH_WIN) | |||
#define DOWNLOADS_ARCH "win" | |||
#elif defined(ARCH_MAC) | |||
#define DOWNLOADS_ARCH "mac" | |||
#elif defined(ARCH_LIN) | |||
#define DOWNLOADS_ARCH "lin" | |||
#endif | |||
json_t *archJ = json_object_get(downloadsJ, DOWNLOADS_ARCH); | |||
if (archJ) { | |||
// Get download URL | |||
json_t *downloadJ = json_object_get(archJ, "download"); | |||
if (downloadJ) | |||
download = json_string_value(downloadJ); | |||
// Get SHA256 hash | |||
json_t *sha256J = json_object_get(archJ, "sha256"); | |||
if (sha256J) | |||
sha256 = json_string_value(sha256J); | |||
} | |||
} | |||
// Append token and version to download URL | |||
std::string url = gApiHost; | |||
url += "/download"; | |||
url += "?product="; | |||
url += slug; | |||
url += "&version="; | |||
url += requestEscape(gApplicationVersion); | |||
url += "&token="; | |||
url += requestEscape(gToken); | |||
json_t *productIdJ = json_object_get(pluginJ, "productId"); | |||
if (productIdJ) { | |||
download = gApiHost; | |||
download += "/download"; | |||
download += "?slug="; | |||
download += slug; | |||
download += "&token="; | |||
download += requestEscape(gToken); | |||
} | |||
if (download.empty()) { | |||
warn("Could not get download URL for plugin %s", slug.c_str()); | |||
return; | |||
} | |||
// If plugin is not loaded, download the zip file to /plugins | |||
downloadName = name; | |||
@@ -227,21 +248,127 @@ static void refreshPurchase(json_t *pluginJ) { | |||
std::string pluginsDir = assetLocal("plugins"); | |||
std::string pluginPath = pluginsDir + "/" + slug; | |||
std::string zipPath = pluginPath + ".zip"; | |||
bool success = requestDownload(url, zipPath, &downloadProgress); | |||
bool success = requestDownload(download, zipPath, &downloadProgress); | |||
if (success) { | |||
if (!sha256.empty()) { | |||
// Check SHA256 hash | |||
std::string actualSha256 = requestSHA256File(zipPath); | |||
if (actualSha256 != sha256) { | |||
warn("Plugin %s does not match expected SHA256 checksum", slug.c_str()); | |||
return; | |||
} | |||
} | |||
// Unzip file | |||
int err = extractZip(zipPath.c_str(), pluginsDir.c_str()); | |||
if (!err) { | |||
// Delete zip | |||
remove(zipPath.c_str()); | |||
// Load plugin | |||
loadPlugin(pluginPath); | |||
// loadPlugin(pluginPath); | |||
} | |||
} | |||
downloadName = ""; | |||
} | |||
static bool trySyncPlugin(json_t *pluginJ, json_t *communityPluginsJ, bool dryRun) { | |||
std::string slug = json_string_value(pluginJ); | |||
// Find community plugin | |||
size_t communityIndex; | |||
json_t *communityPluginJ = NULL; | |||
json_array_foreach(communityPluginsJ, communityIndex, communityPluginJ) { | |||
json_t *communitySlugJ = json_object_get(communityPluginJ, "slug"); | |||
if (communitySlugJ) { | |||
std::string communitySlug = json_string_value(communitySlugJ); | |||
if (slug == communitySlug) | |||
break; | |||
} | |||
} | |||
if (communityIndex == json_array_size(communityPluginsJ)) { | |||
warn("Plugin sync error: %s not found in community", slug.c_str()); | |||
return false; | |||
} | |||
// Get community version | |||
std::string version; | |||
json_t *versionJ = json_object_get(communityPluginJ, "version"); | |||
if (versionJ) { | |||
version = json_string_value(versionJ); | |||
} | |||
// Check whether we already have a plugin with the same slug and version | |||
for (Plugin *plugin : gPlugins) { | |||
if (plugin->slug == slug) { | |||
// plugin->version might be blank, so adding a version of the manifest will update the plugin | |||
if (plugin->version == version) | |||
return false; | |||
} | |||
} | |||
if (!dryRun) | |||
syncPlugin(communityPluginJ); | |||
return true; | |||
} | |||
bool pluginSync(bool dryRun) { | |||
if (gToken.empty()) | |||
return false; | |||
bool available = false; | |||
// Download my plugins | |||
json_t *reqJ = json_object(); | |||
json_object_set(reqJ, "version", json_string(gApplicationVersion.c_str())); | |||
json_object_set(reqJ, "token", json_string(gToken.c_str())); | |||
json_t *resJ = requestJson(METHOD_GET, gApiHost + "/plugins", reqJ); | |||
json_decref(reqJ); | |||
// Download community plugins | |||
json_t *communityResJ = requestJson(METHOD_GET, gApiHost + "/community/plugins", NULL); | |||
if (!dryRun) { | |||
isDownloading = true; | |||
downloadProgress = 0.0; | |||
downloadName = ""; | |||
} | |||
if (resJ && communityResJ) { | |||
json_t *errorJ = json_object_get(resJ, "error"); | |||
json_t *communityErrorJ = json_object_get(resJ, "error"); | |||
if (errorJ) { | |||
warn("Plugin sync error: %s", json_string_value(errorJ)); | |||
} | |||
else if (communityErrorJ) { | |||
warn("Plugin sync error: %s", json_string_value(communityErrorJ)); | |||
} | |||
else { | |||
// Check each plugin in list of my plugins | |||
json_t *pluginsJ = json_object_get(resJ, "plugins"); | |||
json_t *communityPluginsJ = json_object_get(communityResJ, "plugins"); | |||
size_t index; | |||
json_t *pluginJ; | |||
json_array_foreach(pluginsJ, index, pluginJ) { | |||
if (trySyncPlugin(pluginJ, communityPluginsJ, dryRun)) | |||
available = true; | |||
} | |||
} | |||
} | |||
if (resJ) | |||
json_decref(resJ); | |||
if (communityResJ) | |||
json_decref(communityResJ); | |||
if (!dryRun) { | |||
isDownloading = false; | |||
} | |||
return available; | |||
} | |||
//////////////////// | |||
// plugin API | |||
//////////////////// | |||
@@ -271,10 +398,10 @@ void pluginInit() { | |||
void pluginDestroy() { | |||
for (Plugin *plugin : gPlugins) { | |||
// Free library handle | |||
#if ARCH_WIN | |||
#if defined(ARCH_WIN) | |||
if (plugin->handle) | |||
FreeLibrary((HINSTANCE)plugin->handle); | |||
#elif ARCH_LIN || ARCH_MAC | |||
#elif defined(ARCH_LIN) || defined(ARCH_MAC) | |||
if (plugin->handle) | |||
dlclose(plugin->handle); | |||
#endif | |||
@@ -315,39 +442,6 @@ void pluginLogOut() { | |||
gToken = ""; | |||
} | |||
void pluginRefresh() { | |||
if (gToken.empty()) | |||
return; | |||
isDownloading = true; | |||
downloadProgress = 0.0; | |||
downloadName = ""; | |||
json_t *reqJ = json_object(); | |||
json_object_set(reqJ, "token", json_string(gToken.c_str())); | |||
json_t *resJ = requestJson(METHOD_GET, gApiHost + "/purchases", reqJ); | |||
json_decref(reqJ); | |||
if (resJ) { | |||
json_t *errorJ = json_object_get(resJ, "error"); | |||
if (errorJ) { | |||
const char *errorStr = json_string_value(errorJ); | |||
warn("Plugin refresh error: %s", errorStr); | |||
} | |||
else { | |||
json_t *purchasesJ = json_object_get(resJ, "purchases"); | |||
size_t index; | |||
json_t *purchaseJ; | |||
json_array_foreach(purchasesJ, index, purchaseJ) { | |||
refreshPurchase(purchaseJ); | |||
} | |||
} | |||
json_decref(resJ); | |||
} | |||
isDownloading = false; | |||
} | |||
void pluginCancelDownload() { | |||
// TODO | |||
} | |||
@@ -4,6 +4,7 @@ | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <curl/curl.h> | |||
#include <openssl/sha.h> | |||
namespace rack { | |||
@@ -79,6 +80,7 @@ json_t *requestJson(RequestMethod method, std::string url, json_t *dataJ) { | |||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, reqStr); | |||
std::string resText; | |||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); | |||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeStringCallback); | |||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &resText); | |||
@@ -130,6 +132,8 @@ bool requestDownload(std::string url, std::string filename, float *progress) { | |||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); | |||
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferInfoCallback); | |||
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, progress); | |||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, true); | |||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); | |||
info("Downloading %s", url.c_str()); | |||
CURLcode res = curl_easy_perform(curl); | |||
@@ -153,5 +157,36 @@ std::string requestEscape(std::string s) { | |||
return ret; | |||
} | |||
std::string requestSHA256File(std::string filename) { | |||
FILE *f = fopen(filename.c_str(), "rb"); | |||
if (!f) | |||
return ""; | |||
uint8_t hash[SHA256_DIGEST_LENGTH]; | |||
SHA256_CTX sha256; | |||
SHA256_Init(&sha256); | |||
const int bufferLen = 1 << 15; | |||
uint8_t *buffer = new uint8_t[bufferLen]; | |||
int len = 0; | |||
while ((len = fread(buffer, 1, bufferLen, f))) { | |||
SHA256_Update(&sha256, buffer, len); | |||
} | |||
SHA256_Final(hash, &sha256); | |||
delete[] buffer; | |||
fclose(f); | |||
// Convert binary hash to hex | |||
char hashHex[64]; | |||
const char hexTable[] = "0123456789abcdef"; | |||
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { | |||
uint8_t h = hash[i]; | |||
hashHex[2*i + 0] = hexTable[h >> 4]; | |||
hashHex[2*i + 1] = hexTable[h & 0x0f]; | |||
} | |||
std::string str(hashHex, sizeof(hashHex)); | |||
return str; | |||
} | |||
} // namespace rack |